ngOnInit don't execute when using router.navigate

757 Views Asked by At

I've this simple app where '/personas' shows a list of Persona objects. There is also a button to add another person, which send to you to /personas/agregar. There you can create a new object and send it to firebase. Once you do it, the server should take you to /personas again and you should see all objects, however it doesn't shows the new one unless you refresh.

This is the code (when you submit the form it trigger guardarPersona() method):

personas.component.ts:

export class PersonasComponent implements OnInit {

  personas: Persona[] = [];

  constructor(private personasService: PersonasService, private router: Router){}

  ngOnInit(): void {

    this.personasService.obtenerPersonas().subscribe(
      (personas: Persona[]) => {
        this.personas = personas;
        this.personasService.setPersonas(personas);
      }
    );

  }
  
  personaAgregada(persona: Persona){
    this.personas.push(persona);
  }

  agregar(){
    this.router.navigate(['personas/agregar'])
  }

}

formulario.component.ts:

guardarPersona(){
    if(this.id){
      this.personasService.modificarPersona(this.id, this.nombreInput, this.apellidoInput);
    }else{
      this.personasService.agregarPersona(new Persona(this.nombreInput, this.apellidoInput));
    }
    this.router.navigate(['personas']);
  }

persona.service.ts:

setPersonas(personas: Persona[]){
    this.personas = personas;
  }

  obtenerPersonas(){
    return this.dataService.cargarPersonas();
  }

agregarPersona(persona: Persona) {
    if(this.personas == null){
      this.personas = [];
    }
    this.personas.push(persona); 
    this.dataService.guardarPersonas(this.personas);
  }

data.services.ts:

cargarPersonas(){
        return this.httpClient.get<Persona[]>('https://listado-personas-53faf-default-rtdb.firebaseio.com/personas.json');
    }
    

    guardarPersonas(personas: Persona[]){
        this.httpClient.put(this.url + '.json', personas).subscribe(
            response => {console.log(`Datos enviados correctamente: ${response}`)},
            error => {console.log(`Error al enviar los datos: ${error}`)}
        );
    }

I've tried to solve it following this, using NgZone but it din't worked:

this.ngZone.run(() =>i {
    this.router.navigateByUrl('personas');
    });

I also tried with reloading the page after navigate but it neither send the information to firebase:

this.router.navigate(['personas']).then(() => {
    window.location.reload();
});

Then I tried with modifying ngOnInit based in this thread:

ngOnInit() {    
    this.router.events.subscribe(
      (event: Event) => {
             if (event instanceof NavigationEnd) {
                  this.personasService.obtenerPersonas().subscribe(
                    (personas: Persona[]) => {
                      this.personas = personas;
                      this.personasService.setPersonas(personas);
                    }
                  );
             }
      });
  }

But I get no overload matches this call error

1

There are 1 best solutions below

2
Manu On

Doing some test I realized that I was wrong, ngOnInit() was executing after navigate(), however it wasn't showing the updated list because guardarPersonas() takes too long and ngOnInit() gets the list before it's updated.

I "solve" this by setting a timeout on navigate(), but I wonder if it's a better way to do this, for example waiting for httpClient.put to finish.