Goal: To add an object to an existing Observable array of objects. Having this reflect on the DOM is the final step.
NewObject.ts:
export class NewObject {
name: string;
title: string;
}
Here's the example.component.ts:
import { Observable } from 'rxjs';
import { Component, OnInit, Inject, EventEmitter } from '@angular/core';
import { NewObject } from 'objects';
@Component({
selector: 'app-example',
templateUrl: './example.component.html',
styleUrls: ['./example.component.css']
})
export class ExampleComponent implements OnInit {
// Initializing the object array Observable from a service (step 1)
readonly objects$: Observable<NewObject[]> = this.objectSvc.getAllObjects("objects").pipe(
map(obj => obj.map(x => ({ name: x.name, title: alterString(x.title) }))),
shareReplay(1)
);
constructor(
private objectSvc: ObjectService
) { }
ngOnInit() {
somethingThatHappensToAdd = (response: any) => {
let data = JSON.parse(response);
data.forEach(x => {
let obj: NewObject = { name: x.name, title: alterString(x.title) }
// Here's where I'm trying to add the obj object into the already existing object array Observable
});
};
somethingThatHappensToDelete = (response: any) => {
let data = JSON.parse(response);
data.forEach(x => {
let obj: NewObject = { name: x.name, title: alterString(x.title) }
// Here's where I'm trying to delete the obj object from the already existing object array Observable
});
};
}
}
This is my example.component.html:
<div *ngFor="let o of objects$ | async">
<p>{{ o.name }}</p>
<p>{{ o.title}}</p>
</div>
Here's my service object.service.ts:
import { Injectable } from '@angular/core';
import { Observable, throwError, of } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { ClientApi, ApiException, NewObject } from '../client-api.service';
@Injectable({
providedIn: 'root'
})
export class ObjectService {
constructor(
private clientApi: ClientApi
) { }
getAllObjects(name: string): Observable<NewObject[]> {
return this.clientApi.getAllObjects(name)
.pipe(
map((x) => x.result),
catchError(err => {
if (ApiException.isApiException(err)) {
if (err.status === 404) {
return of<NewObject[]>(undefined);
}
}
return throwError(err);
})
);
}
}
After formatting of the response in JSON, I want to be able to insert the obj object into objects$ Observable and have it reflect on the UI.
I am advised to use a BehaviorSubject element to make this happen. Can anyone advise on how this can be easily done?
You can create a BehaviorSubject to emit results coming from somethingThatHappens() and use combineLatest() to merge the results with the ones coming from the service.
objectsFromService$ = this.objectSvc.getAllObjects("objects").pipe(
map(obj => obj.map(x => ({ name: x.name, title: alterString(x.title) })))
);
resultsArray = []
resultsSubject = new BehaviorSubject(this.resultsArray);
results$ = this.resultsSubject.asObservable()
readonly objects$: Observable<NewObject[]> = combineLatest(
this.results$,
this.objectsFromService$
).pipe(
map(([results, objects]) => ([...results, ...objects])),
shareReplay(1)
)
somethingThatHappens = (response: any) => {
let data = JSON.parse(response);
data.forEach(x => {
let obj: NewObject = { name: x.name, title: alterString(x.title) }
this.resultsArray.push(obj)
});
this.resultsSubject.next(this.resultsArray)
};
I created a working stackblitz project: https://stackblitz.com/edit/angular-jnngwh
Hope this gives you a clue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With