component file:
// Angular and 3rd party libs imports
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
import { Store } from '@ngrx/store';
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
// Utils
import { ApiLoadInfo, ApiStateEnum } from 'src/app/shared/utils/states';
// Services
import { TestPortalService } from '../../../testportal.service';
import { SharedClient } from 'src/app/shared/services/shared.service';
// Redux
import {
CandidateInstructionsState,
Quiz,
Instruction,
PageEnum,
LandingPageData
} from '../redux/candidate-instructions.state';
import * as instructionActions from '../redux/candidate-instructions.action';
import * as instructionSelects from '../redux/candidate-instructions.selector';
import { ActivatedRoute } from '@angular/router';
@UntilDestroy()
@Component({
selector: 'candidate-instructions-landing',
templateUrl: './instructions-landing.component.html',
styleUrls: ['./instructions-landing.component.scss', '../common.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class CandidateInstructionsLandingComponent implements OnInit {
// Exposing constants to html template
ApiStateEnum = ApiStateEnum;
PageEnum = PageEnum;
// Variables
initDataLoadState: ApiLoadInfo;
data: LandingPageData;
constructor(private _store: Store<CandidateInstructionsState>,
private _activatedRoute: ActivatedRoute,
private _testPortalService: TestPortalService,
) {
_store
.select(instructionSelects.selectInitDataLoadState)
.pipe(untilDestroyed(this))
.subscribe((initDataLoadState) => {
console.log('is same ref?:', this.initDataLoadState === initDataLoadState)
this.initDataLoadState = initDataLoadState;
console.log(initDataLoadState)
console.log('----------')
});
_store
.select(instructionSelects.selectLandingData)
.pipe(untilDestroyed(this))
.subscribe((data) => {
this.data = data;
});
}
ngOnInit() {
this.loadInstructions();
}
loadInstructions() {
this._store.dispatch(instructionActions.setInitData()); // sets state to 'loading'
this._testPortalService.getTestInstructions(
this._activatedRoute.snapshot.params.quizOrInviteId,
(error, response) => {
if (error) {
// sets state to 'error'
this._store.dispatch(instructionActions.setInitDataFail({ errmsg: error.toString() }));
} else {
// sets state to 'loaded'
this._store.dispatch(instructionActions.setInitDataSuccess({ instructions: response }));
console.log(response);
}
}
);
}
}
html:
{{ initDataLoadState.state }}
I thought when onPush is set, the template will re-render if the variable ref is changed. And since redux store is immutable that is always supposed to happen (confirmed by logging in the console). But still the actual component data is not in sync with the UI ie. component value = "loaded" but value in ui = "loading". Why is it so?