0

I'm pretty new using angular, and overall using JHipster. Right now, I'm having trouble using the filtering provided by JHipster. To load a page, I need to get all the following data:

  • The subject (obtained from the activatedRoute)

  • The Themes (that are part of the subject)

  • The Subthemes (that are part of each theme obtained)

  • The activities (that are part of each subtheme obtained)

The way I'm doing this is in the ngOnInit function:

ngOnInit() {
    this.activatedRoute.data.subscribe(({ subject }) => {
      this.subject = subject;
    });

    this.themeService.query({
      'subject.equals': this.subject.id
    }).subscribe((res: HttpResponse<ITheme[]>) => (this.themes = res.body), (res: HttpErrorResponse) => this.onError(res.message));

    const themesIds = this.themes.map(({ id }) => id);

    this.subthemeService.query({
      'theme.in': themesIds
    }).subscribe((res: HttpResponse<ISubtheme[]>) => (this.subthemes = res.body), (res: HttpErrorResponse) => this.onError(res.message));

    const subthemesIds = this.subthemes.map(({ id }) => id);

    this.activityService.query({
      'subtheme.in': subthemesIds
    }).subscribe((res: HttpResponse<IActivity[]>) => (this.activities = res.body), (res: HttpErrorResponse) => this.onError(res.message));

  }

I expected for each to get every array properly, instead I get this:

ERROR TypeError: Cannot read property 'map' of undefined
    at SubjectPlanComponent.ngOnInit (subject-plan.component.ts?2994:73)
    at checkAndUpdateDirectiveInline (core.js?09c9:19327)
    at checkAndUpdateNodeInline (core.js?09c9:27585)
    at checkAndUpdateNode (core.js?09c9:27547)
    at debugCheckAndUpdateNode (core.js?09c9:28181)
    at debugCheckDirectivesFn (core.js?09c9:28141)
    at Object.eval [as updateDirectives] (SubjectPlanComponent_Host.ngfactory.js? [sm]:1)
    at Object.debugUpdateDirectives [as updateDirectives] (core.js?09c9:28133)
    at checkAndUpdateView (core.js?09c9:27529)
    at callViewAction (core.js?09c9:27770)

Again, I have searched for similar problems here but none of them have solved my problem. I've seen posts that explain that it's because of the way it's getting the data (asynchronously), but I haven't quite understood how. Right now I'm only worried about getting this thing working, but an explanation would be handy.

Full code: https://pastebin.com/fXfSZRmG

2 Answers2

2

The issue is, that when you try to access this.themes.map in line const themesIds = this.themes.map(({ id }) => id);. You don't know if the async information is there already: this.themeService.query(...).subscribe()

Try to access themes.map after the subscription is deffered. Like this;

this.themeService.query({'subject.equals': this.subject.id}).subscribe(
    (res: HttpResponse<ITheme[]>) => { 
    this.themes = res.body;
    const themesIds = this.themes.map(({ id }) => id); // at this point we are sure, that this.themes is there
    }, 
    (res: HttpErrorResponse) => this.onError(res.message));

The same is necessary for subthemes.

1

That's makes sense to me. The error here comes b because of the async concept in js. you can know more about it here Asynchronous JavaScript

Observable is an asynchronous APIs provided by RXJS lib to handle the operations that you have no idea when it should be done just like making an HTTP request.

you can read more about RXJS from here RXJS DOCs and in your case you need to know about observable I hope that the angular docs help you obsevables

Tawfiek Khalaf
  • 497
  • 4
  • 18