3

I'm getting troubles storing data from a returned promise.

To ensure that the value I want has indeed been returned I log it like this.

private fetchData() {
    this._movieFranchiseService.getHighestGrossingFilmFranchises()
      .then((franchises: FilmFranchise[]) => {
        console.log(franchises)
    });
}

But now I want to store it.

private franchises: FilmFranchise[] = [];

private fetchData() {
    this._movieFranchiseService.getHighestGrossingFilmFranchises()
      .then((franchises: FilmFranchise[]) => this.franchises = franchises);
    console.log(this.franchises);
}

All I get with this code is an empty array. So why isn't this.franchises assigned correctly ?

Additional model, mock and service

export class FilmFranchise {
  id: number;
  name: string;
  revenue: number; // Revenue in billion U.S dollars
}

export var FRANCHISES: FilmFranchise[] = [
    { id: 1, name: 'Marvel Cinematic Universe', revenue: 13.47 },
    { id: 2, name: 'J.K Rowling\'s Wizarding World', revenue: 8.54 },
    { id: 3, name: 'Star Wars', revenue: 7.52 },
    { id: 4, name: 'James Bond', revenue: 7.04 },
    { id: 5, name: 'Middle Earth', revenue: 5.88 }
];

public getHighestGrossingFilmFranchises() {
  return Promise.resolve(FRANCHISES);
}

Thanks

3
  • Did you make the change I suggested in my answer below? Even with the change the code you have above is still going to always log an empty array. Commented Mar 13, 2018 at 3:12
  • I did and the log is indeed correct. I understand that I can't access it right away because it is not asynchronous. Now what can I do to be able to access it ? Commented Mar 13, 2018 at 3:17
  • I'll expand my answer below. Commented Mar 13, 2018 at 3:20

1 Answer 1

5

I would guess that the problem is with your logging, not your data access.

If the get method you are using is asynchronous, you cannot log it's value immediately after the call. You have to do it within the callback.

Something like this:

private fetchData() {
    this._movieFranchiseService.getHighestGrossingFilmFranchises()
      .then((franchises: FilmFranchise[]) => {
          this.franchises = franchises);
          console.log(this.franchises);
       }
}

I changed the single line callback to a multi-line callback by adding another set of braces. Now both lines are within the callback.

EDIT

A few things about managing data from an Http call.

As you know, Http is asynchronous, so you have to wait for the data to be returned in the response before you can use it.

Angular most often uses Observables (not promises) to work with http data.

A service will retrieve the data and return the Observable.

Any component that needs to work with the data will subscribe to the Observable. The component can then work with that data in the function provided to the subscribe method.

As an example, here is a simple "movie" service:

getMovies(): Observable<IMovie[]> {
    return this.http.get<IMovie[]>(this.moviesUrl);
}

It returns an observable.

Here is a simple component that uses the service:

ngOnInit(): void { 
    this.movieService.getMovies()
        .subscribe(
            (movies: IMovie[]) => {
                this.movies = movies;
                this.filteredMovies = this.performFilter(this.listFilter);
            },
            (error: any) => this.errorMessage = <any>error);
}

Any code that we want to work with the data is within the subscribe.

Hope this helps.

Sign up to request clarification or add additional context in comments.

3 Comments

Not sure how this can help me. Array this.franchises is still empty if I try to log it later.
I think you need to read this carefully and make sure you are calling it right. I'm able to also log the this.franchises
I understand the synchronicity issue and the need of Observable. Thanks for the edit.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.