Home > Net >  Angular NgOnInit executing method before another
Angular NgOnInit executing method before another

Time:03-12

I have an angular application where I am trying to get an array of sources for an image carousel. How I have it set up currently I have a "getUrls()" method to get the urls from the database like so

http.service.ts:

getUrls() {
    this.http
      .get<string[]>(
        '<DATABASE_LINK>'
      )
      .subscribe((imageUrls: string[]) => {
        this.carouselService.setUrls(imageUrls);
      });
  }

That method calls the method "setUrls" to set them into an array stored in a service

carousel.service.ts:

  urls: string[] = [];

  constructor() {}

  setUrls(urls: string[] | []) {
    this.urls = urls || [];
    debugger;
  }

  getImages() {
    debugger;
    return this.urls;
  }

Then inside of the carousel component I call both of the previous methods in ngOnInit

image-carousel.component.ts:

  ngOnInit(): void {
    this.httpService.getUrls();
    this.images = this.cService.getImages();
  }

This would then assign the values set by the "setUrls()" method, but for some reason, it is reaching the "getImages()" method before setting the Urls.

I got it to work by taking the "getImages()" line into a separate method and clicking a button to call it, so that I could make sure that everything worked in the right order and it did, however I want it to do all of that when the components are initialized.

I am sure I am missing something, so anything helps, even if I have to refactor a lot.

I tried to use a ".pipe(tap()" in the "getUrls()" method instead of a subscribe, however it would never call the "setUrls()" method.

CodePudding user response:

Since getUrls() perform its work asynchronously, you have no idea when it completes and return imageUrls. You'll have to refactor your code a little, like this

getUrls():Observable<string[]> {
return this.http
  .get<string[]>(
    '<DATABASE_LINK>'
  );
  }

and your ngOnInit method would get updated like this

  ngOnInit(): void {
this.httpService.getUrls()
.subscribe((imageUrls:string[])=>
 {
   this.images = imageUrls;
  });
 }

CodePudding user response:

The function in the service getUrls() is an asynchronous one. Therefore you have to wait for it to be resolved. You can use the observables for this to achieve. You need to simply subscribe the getUrls() and put the get images function call in the subscription block.

CodePudding user response:

As getUrls() performing a asynchronous task which is http.get,you have to wait to get images until asynchronous task gets completed.

So one of the possible solution could be,you can return observable from your http.service.ts service and inside component ngOnInit you can fetch images inside subscription.

http.service.ts:

getUrls() {
    this.http
      .get<string[]>(
        '<DATABASE_LINK>'
      )
      .pipe(
         map((imageUrls: string[]) => {
            this.carouselService.setUrls(imageUrls);
         })  
       );
  }

carousel.service.ts:

  urls: string[] = [];

  constructor() {}

  setUrls(urls: string[] | []) {
    this.urls = urls || [];
    debugger;
  }

  getImages() {
    debugger;
    return this.urls;
  }

image-carousel.component.ts:

ngOnInit(): void {
    this.httpService
        .getUrls()
        .subscribe(
          () => {
             this.images = this.cService.getImages();
          }
        );
  }
  • Related