I have a list of labels in NativeScript app representing a status. I have method that changes the status of each label after tap. After I tap the label it should change the status value (number) and show new value on the screen right after the tap.
What I've done is partially working. I have to tap it twice to see the label changed, or tap once and pull to refresh to see the label change. Also update in the service is working as expected after tap. Any ideas how to implement this behavior properly?
Views: parent component:
<StackLayout *ngFor="let phase of (training$ | async)?.phases; let i = index">
<StackLayout *ngIf="(training$ | async)?.phases">
<StackLayout>
<ns-phase-item [phase]="phase" [training$]="training$" [i]="i"></ns-phase-item>
</StackLayout>
</StackLayout>
</StackLayout>
First child (ns-phase-item):
<StackLayout>
<Label [text]="phase.phaseTitle" [textWrap]="true" class="title-wrap"></Label>
<StackLayout *ngFor="let unit of (training$ | async).phases[i].units">
<ns-unit-item [unit]="unit" class="unit"></ns-unit-item>
</StackLayout>
</StackLayout>
Child of first child view (ns-unit-item) (where I call the update method):
<StackLayout [ngClass]="{ 'unit-completed': unit.status === 1, 'unit-not-completed': unit.status !== 1 }">
<GridLayout columns="4*, *" rows="auto">
<FlexboxLayout col="0" flexDirection="row" (tap)="onView(unit._id)">
<Label [text]="(unit.date | date: 'd. MMM') + ' - ' + unit.unitTitle"></Label>
<Label *ngIf="unit.duration || unit.distance" text=" ("></Label>
<Label *ngIf="unit.duration" [text]="' ' + unit.duration + ' min'"></Label>
<Label *ngIf="unit.duration && unit.distance" text=" / "></Label>
<Label *ngIf="unit.distance" [text]="unit.distance + ' km'"></Label>
<Label *ngIf="unit.duration || unit.distance" text=")"></Label>
<Label *ngIf="unit$" [text]="(unit$ | async).status"></Label>
</FlexboxLayout>
<StackLayout col="1">
<StackLayout *ngIf="(unit$ | async).status == 1">
// HERE I CALL UPDATE - it should change the value and icon after tap
<Image src="res://check" height="20" stretch="aspectFit" (tap)="onStatusUpdate(0)"></Image>
</StackLayout>
<StackLayout *ngIf="(unit$ | async).status == 0">
<Image src="res://checkgray" height="20" stretch="aspectFit" (tap)="onStatusUpdate(1)"></Image>
</StackLayout>
</StackLayout>
</GridLayout>
</StackLayout>
Child of first child controller (ns-unit-item component)
private _unit: BehaviorSubject<Unit> = new BehaviorSubject<Unit>(null)
getUnitObservable(): Observable<Unit> {
return this._unit.asObservable()
}
getUnitValue(): Unit {
return this._unit.getValue()
}
unitChanged(unit: Unit) {
this._unit.next(unit)
}
ngOnInit(): void {
this.unitChanged(this.unit)
this.unit = this.getUnitValue()
this.unit$ = this.getUnitObservable()
}
onStatusUpdate(status: number) {
this.trainingService.updateTrainingUnitStatus(this.unit._id, status).subscribe((unit) => {
this.unitChanged(unit)
this.unit$ = this.getUnitObservable()
})
}
Service where I call API
updateTrainingUnitStatus(id: string, status: number) {
return this.http.post<Unit>(`${this.API_URL_UNITS}/${id}/status`, { status: status })
}