In respect to the following code, it would appear that the UI is not updated with the value, yet, I can see the value being set to the field correct.
I have tried 2 different approached, bar have not tried the change detection approach as I believe the one in the code below, should work.
In my service, I listen for the route end event, the reason for this is, that something in the service needs to be changed depending on the existence of a parameter in my route, eg: '/page/:id'.
In one scenario, the the URL might be /page, in another, the /page/12, so based on this fact, I need to return the value from two different services, if the ID does not exist, use SERVICE1 otherwise use SERVICE2.
I basically have a subscribe that returns the value from another subscribe. To do this, I'm relying on Subscribe to emit the value from the inner subscribe, which works (see the examples below). My pain here is, that the UI does not render the values.
MAIN SERVICE
Note: omitted the full class for brevity, just to show the method in question:
get getCourse(): Observable<CoursesDTO> {
let subject = new Subject<CoursesDTO>();
this.router.events.pipe(filter(e => e instanceof NavigationEnd))
.subscribe(x => {
let course: CoursesDTO = {
courseName: '',
courseId: ''
};
const route = this.router.routerState.snapshot.root;
let courseId: string = '';
if (route.children.length >= 1) {
const obj = route.children[route.children.length - 1];
const value = (obj.params as any).value;
// we have a courseID, interact with the course workflow
if (!_.isEmpty(value)) {
this.courseWorkflowProxy.interact(value.courseId, 'CourseMaterial', null)
.subscribe((b: InteractionResponseDTO) => {
const x: CourseDTO = <any>b.workflowResult;
course = {
courseName: x.courseName,
courseId: x.courseId
};
subject.next(course);
subject.complete();
return course; // I don't feel this is necessary
});
}
}
// we don't have the courseID, so assume there is a JWT token
// for example, that authenticated the user + courseID
// and we can get this in the code behind
this.coursesProxy
.getCourseInfo()
.subscribe(b => {
course = {
courseName: b.courseName,
courseId: b.courseid
};
subject.next(course);
subject.complete();
return course; // I don't feel this is necessary
});
});
return subject;
}
Please note, this code has been modified to represent the code, not an "actual" scenario, if this feels wrong, is for demonstration of the code.
The implementation of this method, in a component called WatchBlock.ts, showing one of the possible fixes I tried, via ngZone:
this.whatBlockService.getCourse.subscribe((r: CourseDTO) => {
this._ngZone.run(() => {
this.title = r.courseName;
this.id = r.courseId;
console.dir({ title: this.title, id: this.id }); // this prints the values to the console
});
});
The following code blocks "works" in the sense that it returns the values I'm looking for, however, as stated, it does not appear in the rendered HTML.
The HTML file:
<div fxLayout="row" fxLayoutAlign="start center">
<div class="ml-16">
<label class="identi">{{id}}</label>
</div>
</div>
<div class="px-8 px-mat-16">
<span class="mat-title">{{title}}</span>
</div>
I have tried the BehaviorSubject approach as well, and that did not work for me either.
I didn't try the change detector route, as I feel that ngZone should be doing the change detection itself, if I understand how zoning works.
I can't figure this out, and would appreciate any help from the gurus out there.