I receive a set of data from a guard, the set of data contains the expected data. My problem is to passing the set of data to my component.
This is my code:
export class UserEditorComponent implements OnInit, OnDestroy {
@Input()
user = new User();
constructor(private activatedRoute: ActivatedRoute) {}
private subscription: Subscription | null = null;
ngOnInit(): void {
this.subscription = this.activatedRoute.data.subscribe(x => {
console.log("Incoming data ", x); //the incoming contains the expected data (name & age)
console.log("Class Field user", this.user); //the field "user" is initialized with default values
this.user.Name = x.Name;
this.user.Age = x.Age;
console.log("Check user ", this.user); //user is undefined
});
}
}
What’s wrong here? I look forward to your answers! :-)
Kind regards Christoph
the answer relies on the Angular's Component Lifecycle. Let's check what happens accordingly to the lifecycle of your component:
Here's is what I guess, relying on the piece of code you posted: you initialize the "user" property in the component, giving it a new User instance, but you lose it when Angular try to initialize it from the outside, immediately after the constructor execution.
In other words, if you have a selector like this:
<app-user-editor></app-user-editor>
you have to be sure that a property binding against the "user" property is applied in the parent component, like this:
<app-user-editor [user]="aUserInstance"></app-user-editor>
Furthermore, be sure that the value given to the user property is a User instance as expected in the UserEditorComponent: if you send a non-initialized value (undefined) it will trigger the errors that you are seeing in your console logs.
If I may, the initialization you are performing in your UserEditorComponent is useless, as far as it will be overridden by the incoming value. Use this syntax instead:
@Input() user!: User;
Telling that the user property is an User instance, and that it will be properly initialized after the constructor in some way (the ! character in TypeScript is needed for this) is far enough.
EDIT Checking the code on github, I've seen that the object returned by the Resolver was wrapped into the "user" key, so the x parameter on the resolver's subscription was accessed improperly:
this.subscribtion = this.activatedRoute.data.subscribe(x => {
this.user.Name = x..user.Name; // Was this.user.Name = x.Name
this.user.Age = x.user.Age; // Was this.user.Age = x.Age;
});
}
When a Resolver returns something, it wraps the data in an object with the same key used in the Router config (following, the user's repo Router):
const routes: Routes = [
{
path: 'user', component: UserComponent,
children: [
{
path: ':name',
component: UserEditorComponent,
resolve: {
// Data returned by the UserGuard Resolver is placed into the "user" key
// so, subscribing to the resolver Observable, will return an object with
// user: {Age: number, Name: string}
user: UserGuard
}
},
],
}
];
If you want to check all the improvements made, you can go to the pull request I've made on the user's repo https://github.com/Christoph1972/routing-guard-test/pull/1