He hecho una aplicación básica para administrar una base de datos. Los datos se presentan en una tabla y botones para eliminar cada elemento. Por alguna razón, al eliminar un elemento, los datos no se actualizan con el primer clic del botón, sino con el segundo. La segunda vez que se hace clic en el botón, la consola genera un error 404 para la solicitud http, porque el elemento no existe.
Me pregunto por qué los datos no se recargan antes de esa fecha. Este es mi componente:
import { Component, OnInit } from '@angular/core'; import { BackendService } from 'src/app/backend.service'; import { ICity } from '../interfaces/city'; import { ICountry } from '../interfaces/country'; @Component({ selector: 'app-cities', templateUrl: './cities.component.html', styleUrls: ['./cities.component.css'] }) export class CitiesComponent implements OnInit { public countries: ICountry[] = []; public cities: ICity[] = []; constructor(private _backendService: BackendService) { } ngOnInit(): void { this.loadCities(); this.loadCountries(); } loadCities() { this._backendService.getCities().subscribe(data => { this.cities = JSON.parse(JSON.stringify(data)).cities; }); } loadCountries() { this._backendService.getCountries().subscribe(data => { this.countries = JSON.parse(JSON.stringify(data)).countries; }); } submit(city: ICity) { this.remove(city); this.ngOnInit(); } remove(city: ICity): void { this.countries.forEach((cn) => { if (cn.majorCities.find(c => c.name == city.name)) { console.log(cn); this._backendService.removeCity(cn.name.toLowerCase(), city.name.toLowerCase()).subscribe(data => console.log(data)); } }); } }Modelo:
<h1>Cities</h1> <tbody> <tr> <td><h3>City</h3></td> <td><h3>Population</h3></td> <td><h3>Area in km²</h3></td> <td><h3>City Rank</h3></td> </tr> <tr *ngFor="let city of cities"> <td>{{ city.name }}</td> <td>{{ city.population }}</td> <td>{{ city.area }}</td> <td>{{ city.rank }}</td> <button type="button" (click)="submit(city)">Delete</button> </tr> </tbody>Es posible que tenga una condición de carrera aquí. Está enviando una solicitud de eliminación, pero realizando una actualización antes de que se reciba y gestione una respuesta. Cuando trabaje con suscripciones RxJS, puede hacer lo siguiente...
this._backendService.removeCity(cn.name.toLowerCase(), city.name.toLowerCase()).subscribe( // This is the callback for when the response was successful. // No error was caught during the request. (data) => { // You can attempt a refresh here because we know the request has // completed and the row was deleted. this.refresh(); }, // This is the callback for when the response was not successful. // The backend service threw some sort of error, or the code ran into an error // during execution. You can handle the error here (display some message). (error) => { // Do something in response to the error. } // This is the code to run when the Observable has communicated that it has // completed. The observable has said "I'm done sending messages, there will be // no more," so do whatever you need to in response to that. () => { // Do something... } ); Tampoco recomendaría usar ngOnInit para su operación de actualización, ya que es un método reservado utilizado por Angular ; puede encontrar que, al llamar a ngOnInit , se está haciendo más de lo que piensa.
ngOnInit() { this.refresh(); } public refresh(): void { // Your refresh logic here. }