-2

I am trying to make an HTTP get request at takes a userId as a parameter and returns a single user profile using Angular, but keep getting undefined data returned. I know the problem isn't with my backend server because the same HTTP get request with Postman works correctly. Also, I am getting this exception (backend is written in Java) from my Angular HTTP request, but not from the Postman HTTP request.

profile.component.ts:

profile: Profile;
constructor(private profileService: ProfileService) {
}
ngOnInit() {
  this.getProfile();
}
getProfile() {
  this.profileService.getProfile("5e7bd87e05854a05cc0f6898").subscribe(
    profile => this.profile = profile,
  );
  console.log( this.profile );
}

profile.service.ts:

getProfile(userId: string) {
    let params = new HttpParams().set("id", userId);
    console.log( "executing HTTP get" );

    //return this.httpClient.get<any>( "http://localhost:8080/user", { params: params });
    // I've tried this above method and the one below

    return this.httpClient.get("http://localhost:8080/user", { params: params })
    .pipe(
      map((data: any) => {
        const profile: Profile = new Profile( data.object.id,
                               data.object.username,
                               data.object.password,
                               data.object.fname,
                               data.object.lname,
                               data.object.email,
                               data.object.joined );
        return profile;
      })
    );
   }

The console.log( this.profile ) just comes out as undefined in the browser console. I think I'm using subscribe incorrectly. Anyone know what I'm doing wrong?

EDIT: Here is a screenshot of the error from the browser console. Not sure if it's relevant.

2 Answers2

2

The call this.profileService.getProfile() returns an Observable that is async. So the call flow is doing this:

  • this.profileService.getProfile("5e7bd87e05854a05cc0f6898") starts the HTTP request
  • console.log(this.profile) gets called (It is undefined because it hasn't been set yet)
  • sometime in the future: the HTTP requests finishes
  • THEN, your callback function in your .subscribe() runs. (in your case profile => this.profile = profile,)

To fix your issue, just move your console.log into your .subscribe() callback.

getProfile() {
  this.profileService.getProfile("5e7bd87e05854a05cc0f6898").subscribe(profile => {
    this.profile = profile;
    console.log( this.profile );
  });
}

I am not sure how that error is related because you haven't posted your notifications.service.ts code. It could be related to how you are setting the profile, but I cannot tell without seeing that other code. Same for the Java error. Not sure what the difference is between your Postman request and your Angular request.

Fixing the console.log will solve your undefined error. Hopefully that will help you figure out the Java error. That Java error appears to be related to a Web Socket or something. Just taking a wild guess, but I doubt your HTTP call to fetch your user's profile is causing that error.

DJ House
  • 1,307
  • 1
  • 11
  • 14
  • Thanks so much. Yeah I just remembered the notifications error is because it's a microservice that wasn't running at that time. The problem is fixed but the Java error is still present so it must be unrelated. Thanks! – Jedediah Heal Apr 02 '20 at 21:14
  • Do you have a recommendation as to how to access that profile information from the html code AFTER the request has been completed? – Jedediah Heal Apr 02 '20 at 21:16
  • Do you have an existing `profile.component.html` file you want to share? The best way to _safely_ is to use Angular's [safe navigation operator](https://angular.io/guide/template-syntax#the-safe-navigation-operator----and-null-property-paths) `?`. For example, in your html: `

    {{profile?.name}}

    ` That won't display anything until `this.profile` is loaded. It also won't error if `this.profile` is `undefined`.
    – DJ House Apr 03 '20 at 12:36
1

The HTTP requests are resolved asynchronously so when you print console.log( this.profile ); the GET request is still not resolved and therefore the value assigned to this.profile is still undefined. If you want to see the value just put the console.log( this.profile ); inside the subscribe after you are doing the assigment profile => this.profile = profile,.

  • I changed it to `subscribe( profile => this.profile = profile, console.log( this.profile ); );` but I am getting compilation errors, what exactly would be the correct syntax? – Jedediah Heal Apr 02 '20 at 21:02
  • 1
    You have to wrap your arrow function in brackets since you have two lines in your callback function. See my answer with the brackets in the callback. – DJ House Apr 02 '20 at 21:08
  • And like this? this.profileService.getProfile("5e7bd87e05854a05cc0f6898").subscribe( profile => this.profile = profile; console.log(profile'); ); – Óscar Ferrando Apr 02 '20 at 21:10