简体   繁体   中英

My angular function is not being executed on the first call. It is only being executed on the second call

The title is really not clear I grant you. I have a variable in a component and I would like to use it in another component. I created a service and observable in order to be able to transmit my data. I send my data to my service then I head to the page that will retrieve this data.

        this.service.myMethod(this.ville);
        this.router.navigateByUrl('tabs/resto-by-ville');

Behind I get my data and use it like this:

getDataByVille() {
    this.service.myMethod$.subscribe((city) => {
        this.city = city;
        this.http.get<Etablissement[]>('http://127.0.0.1:8000/api/etablissements/' + this.city).subscribe((data) => {
            this.dataByVille = data;
            console.log(this.dataByVille);
        });
    });
}

ngOnInit() {
    this.getDataByVille();
}

My service :

export class GetDataByVilleService {
    myMethod$: Observable<string>;
    private myMethodSubject = new Subject<string>();

    constructor() {
        this.myMethod$ = this.myMethodSubject.asObservable();
    }

    myMethod(data) {
        console.log(data);
        this.myMethodSubject.next(data);
    }

My problem is that when I send a data absolutely nothing happens. If I repeat it a second time it will work. I don't understand why it doesn't work the first time. Do you have an idea? Currently it's not very UX friendly

The problem is that a Subject does not store the value, so by the time you reach the 'tabs/resto-by-ville' page, the emit has already happened.

Instead of a Subject, you should use a BehaviorSubject, like:

private myMethodSubject = new BehaviorSubject <string>(null);

The BehaviorSubject stores the last value you gave it, and emits it as soon as you subscribe to it.

You are getting the observable pattern all wrong. They should be chained like this:

Service:

export class GetDataByVilleService {
  getDataByVille(): Observable<Etablissement[]> {
    return this.http.get<Etablissement[]>('http://127.0.0.1:8000/api/etablissements/' + this.city)
  });
}

Component:

// Component under "tabs/resto-by-ville"
export class RestoByVilleComponent {
  dataByVille: Etablissement[];

  constructor(getDataByVilleService: GetDataByVilleService )
  ngOnInit() {
    this.getDataByVilleService.getDataByVille().subscribe(dataByVille => {
      this.dataByVille = dataByVille;
    });
  }
}

There is no need to call the service from the component you want to navigate from.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM