angularobservableangular-resolver

Angular Resolver seems not to update object


Good evening, I need a second pair of eyes, I' am not able to find the issue.

I have a java (Dropwizard) based REST Service that exposes the following service.

@GET
@Path("{personId}")
public Response getPerson(@PathParam("personId") OptionalLong personId)

The corresponding function on the frontend is

  getUserById(userId: number): Observable<User> {
console.log("fetching user for id " + userId);
return this.http.get<User>(this.baseUrl + `/api/authorization/persons/${userId}`,{observe: 'response'}).pipe(
    map(r => {
      let resp = r as HttpResponse<User>;
      console.log("returning resp " + resp.body.name);
      return resp.body;
    })
  );

}

The above function is called by a resolver

import {Injectable} from "@angular/core";
import {ActivatedRouteSnapshot, Resolve, RouterStateSnapshot} from "@angular/router";
import {Observable} from "rxjs";
import {ApiService} from "./api.service";
import {User} from "../model/user.model";

@Injectable()
export class UserResolver implements Resolve<User> {

  constructor(private apiService:ApiService) {

  }

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<User> {
    return this.apiService.getUserById(route.params['userid']);
  }

}

The routing is configured as follows:

{ path: 'users', component: UsersComponent, canActivate: [AuthGuard], children: [
    { path: 'profile/:userid',
    component: UserProfileComponent, canActivate: [AuthGuard],
    resolve:
      {
        user:UserResolver
      }
  },
  { path: '', component: ListUserComponent }

] }

The UserProfileComponent looks like this

import { Component, Input, OnInit} from '@angular/core';
import {ActivatedRoute, Router} from "@angular/router";
import {ApiService} from "../../../core/api.service";
import {AuthenticationService} from "../../../services/authentication.service";
import {AlertService} from "../../../services/alert.service";
import {User} from "../../../model/user.model";

@Component({
  selector: 'app-user-profile',
  templateUrl: './user-profile.component.html',
  styleUrls: ['./user-profile.component.scss']
})
export class UserProfileComponent implements OnInit
{
  @Input() user: User;

  constructor(private router: Router,
          private route: ActivatedRoute,
          private apiService: ApiService,
          private authenticationService: AuthenticationService,
          private alertService: AlertService) { }

  ngOnInit() {
    
    if(!this.authenticationService.currentUserValue) {
      this.router.navigate(['login']);
      return;
    }
    console.log("In UserProfileComponent " + this.user); 
  }
}

I can see that a call to the backend is performed, a user is found and received back by the api, however, the instance in the UserProfileComponent seems not to be updated, and the data is not accessible from the the HTML Template.

enter image description here

I think its somehow because the backend is providing an HTTPResponse and not the user (object) itself (I have other resolvers for other objects (where an object is returned, this works as expected.

Naming of Person and User is subject to refactoring once the functionality is working as expected.

Any help is appreciated, and many thanks in advance,

Eduard


Solution

  • You might have to obtain the resolver data from ActivatedRoute and not using @Input. Try the following

    export class UserProfileComponent implements OnInit {
      user: User;
    
      constructor(
        private router: Router,
        private route: ActivatedRoute,
        ...
      ) { }
    
      ngOnInit() {
        if(!this.authenticationService.currentUserValue) {
          this.router.navigate(['login']);
          return;
        }
        this.user = this.route.data.user;
        console.log("In UserProfileComponent " + this.user); 
      }
    }