First, I am open to other things besides behavior subjects? but this is what is working for me so far. I have a Nativescript app using the Latest Angular7 build and Nativescript 5.1 I am trying to populate a ListView in NS with a json file and its all working good so far. But I would like to do more with the config file than just the initial listview.
import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { BehaviorSubject, Observable, of } from "rxjs";
import { catchError, map, tap } from "rxjs/operators";
import { IMenuItem } from "~/app/menuItem";
@Injectable({
providedIn: "root"
})
export class DataItemService {
items$ = new BehaviorSubject<Array<IMenuItem>>([]);
constructor(private http: HttpClient) { }
clear(): void {
this.items$.next([]);
}
fetch(): Observable<any> {
this.clear();
return this.http.get("https://example.com/config.json")
.pipe(
map((data) => {
return (data["result"]) ? data["result"] : false;
}
),
tap((items) => { if (items) { this.items$.next(items); }}),
catchError((err) => {
return of(false);
})
);
}
}
My question goes like this. Using the code above I am getting a portion of my array in the "result" section. But I would also like to get config as well and save it. Is there a way for me to do the exact same thing I am doing with data["results"] and save it to this.config$ intstead of this.items$
I'd like both objects from the same json but not have to do 2 calls to set it all up. Is there a way I can do 1 call to the JSON and then save off the different objects as behavior subjects ?
{
"config": [
{
"debug": true
}
],
"result": [
{
"id": 0,
"title": "Home",
"titleFontSize": 16,
"iconFontSize": 30,
"subtitle": "This is the subtitle for messages",
"image": "",
"icon": "fa-home",
"url": "/home",
"sidebar": true,
"mainmenu": false,
"bg": "#ffdc00",
"titleColor": "white",
"subtitleColor": "white",
"squarebg": "rgba(0,0,0,.8)"
}
]
}
--- EDIT ---
using the answer as inspiration from below.. i have this
fetch(): Observable<any> {
this.clear();
return this.http.get("https://example.com/config.json")
.pipe(
tap(({start, finish}) => {
if (start) {
this.items$.next(start);
console.log("ITEMS ARE " + JSON.stringify(this.items$.value));
}
if (finish) {
this.config$.next(finish);
console.log("CONFIG IS " + JSON.stringify(this.config$.value));
}
}
));
Now I modified my JSON to have 2 keys. start and finish (because config was complaining that it was already used in some other dependency). so with start and finish in my JSON I do console.log and I get both the keys.. start and finish.
the new issue is that my original call had a MAP which removed all the other crap and just gave me the array with no observable code. the new stuff gives me a bunch of observable content with it.. my current ListView doesn't populate now with the new code even though I know console log is doing what we want (mostly).
<RadListView [items]="items$ | async"
ngOnInit() {
this._dataItemService.fetch().subscribe();
this.items$ = this._dataItemService.items$;
}
You don't really need the map in between, you can extract data with ES6 syntax.
this.http.get("https://example.com/config.json")
.pipe(
tap(({result,config})) => {
if (result) this.items$.next(items);
if (config) this.config$.next(config);
}),
catchError((err) => {
return of(false);
})
);