I am pretty new to Angular, and this has me stumped. So I am trying to call to data using a Subscribe, and I am able to console.log that data inside the subscribe method, but I can not access in information outside of it. I believe I am initializing the property correctly (as least this is the way I keep seeing), but I keep get "undetermined". Can someone please show me what I am doing wrong, or give me a better want to fetch the data than a subscribe method?
@Component({
selector: 'app-maintain',
template: '<div [id]="pageId"</div>'
})
export class MaintainPage implements AfterViewInit, OnChanges, OnDestroy, OnInit {
@Select()
public userName$: any;
public user: any;
public pageId = 'maintainPage';
private readonly destroy$ = new Subject<void>();
public parentData: any = { message: this.userName$};
constructor(
private readonly httpClient: HttpClient,
private readonly sessionService: SessionService,
)
public ngOnInit() {
this.sessionService.getMySessionUsingGET()
.pipe(takeUntil(this.destroy$))
.subscribe((data) => {
this.userName$ = data.account.name;
this.user = data;
console.log("Data: ", data);
console.log("Name: ", data.account.name);
}, error => {
console.log(error);
});
console.log('UserName Outside Method: ', this.userName$); // returns "undetermined"
}
public ngAfterViewInit(): void {
this.render();
}
public ngOnChanges(changes: SimpleChanges){
this.render();
}
public ngOnDestroy(): void {
this.destroy$.next();
this.destroy$plete();
}
private render() {
const root = createRoot(document.getElementById(this.pageId) as HTMLElement);
root.render( React.createElement(MaintainWrapper, { ...this.parentData })
);
console.log('UserName: ', this.userName$); // returns "undetermined"
}
}
I am pretty new to Angular, and this has me stumped. So I am trying to call to data using a Subscribe, and I am able to console.log that data inside the subscribe method, but I can not access in information outside of it. I believe I am initializing the property correctly (as least this is the way I keep seeing), but I keep get "undetermined". Can someone please show me what I am doing wrong, or give me a better want to fetch the data than a subscribe method?
@Component({
selector: 'app-maintain',
template: '<div [id]="pageId"</div>'
})
export class MaintainPage implements AfterViewInit, OnChanges, OnDestroy, OnInit {
@Select()
public userName$: any;
public user: any;
public pageId = 'maintainPage';
private readonly destroy$ = new Subject<void>();
public parentData: any = { message: this.userName$};
constructor(
private readonly httpClient: HttpClient,
private readonly sessionService: SessionService,
)
public ngOnInit() {
this.sessionService.getMySessionUsingGET()
.pipe(takeUntil(this.destroy$))
.subscribe((data) => {
this.userName$ = data.account.name;
this.user = data;
console.log("Data: ", data);
console.log("Name: ", data.account.name);
}, error => {
console.log(error);
});
console.log('UserName Outside Method: ', this.userName$); // returns "undetermined"
}
public ngAfterViewInit(): void {
this.render();
}
public ngOnChanges(changes: SimpleChanges){
this.render();
}
public ngOnDestroy(): void {
this.destroy$.next();
this.destroy$plete();
}
private render() {
const root = createRoot(document.getElementById(this.pageId) as HTMLElement);
root.render( React.createElement(MaintainWrapper, { ...this.parentData })
);
console.log('UserName: ', this.userName$); // returns "undetermined"
}
}
Share
Improve this question
asked 22 hours ago
MtullisMtullis
375 bronze badges
1
- Good morning, I believe your subscribe has to be as: .subscribe({next: (data:any) => {console.log(data)} }); Also, as http requests are asynchronous, "UserName Outside Method:" will resolve before the result on the http request resolves. – Carsten Commented 22 hours ago
1 Answer
Reset to default 0One hook does not wait for another hook to finish, so place all your cascading logic on the same hook.
You can refactor you code to:
public ngAfterViewInit(): void {
this.sessionService.getMySessionUsingGET()
.pipe(takeUntil(this.destroy$))
.subscribe((data) => {
this.userName$ = data.account.name;
this.user = data;
console.log("Data: ", data);
console.log("Name: ", data.account.name);
this.render();
}, error => {
console.log(error);
});
this.render();
}
public ngOnChanges(changes: SimpleChanges){
this.render();
}
Explanation:
Look at this below code, where we expect output to be 1, 2, 3
but it gives 1, 3, 2
, this is because the console.log is wrapped in a setTimeout
, this is because certain actions are asynchronous
(observables
, promises
, setTimeout
, setInterval
, etc) and rest is synchronous
.
Javascript first completes the synchronous code and then executes the asynchronous code.
What the heck is the event loop anyway? | Philip Roberts
console.log(1);
setTimeout(() => {
console.log(2);
})
console.log(3);
So applying this logic to your code, move the console.log inside the subscribe, since if you are dependent on the data inside the subscribe, then the logic should also be placed inside the subscribe.