Although I feel this answer is relatively close to my problem and got some reputation, I don't get it right. I read a lot of posts on how to use the "new" style of Observer-pattern ((...).pipe(map(...)).subscribe(...)
and *ngFor="... | async"
) in Angular and now also stumbled across How to Avoid Observables in Angular. I don't want to avoid reactive behaviour; I want to have changes in the REST-API to be reflected "live" to the user without reloading the Observer. That's why I want to subscribe an object (and therefore also its properties) to an Observable (and the 'might-be-there' values from the data-stream in it), right?
In my template I have:
<p>Werte:<br><span *ngFor="let attribute of _attributes | slice:0:5; index as h">
{{attribute.name}}: <strong>{{getParamNameAt(h)}}</strong> </span><br>
<span *ngFor="let attribute of _attributes | slice:5: _attributes.length; index as h">
{{attribute.name}}: <strong>{{getParamNameAt(h + 5)}}</strong> </span></p>
In my component I have:
private _attributes: Attribute[];
constructor(private attributesService: BkGenericaAttributesService) {
attributesService.getAttributes().subscribe({ next: attributes => this._attributes = attributes });
}
getParamNameAt(h: number): string {
let attrVal = this.bkHerstArtNr.charAt(h);
return attributes[h].subModule.find(param => param.subModuleValue === attrVal).subModuleName;
}
and as service I have:
const localUrl = '../../assets/json/response.json';
@Injectable()
export class BkGenericaAttributesMockService implements BkGenericaAttributesService {
constructor(private http: HttpClient) {
}
getAttributes(): Observable<Attribute[]> {
return this.http.get<Attribute[]>(localUrl).pipe(
tap((attributes : Attribute[]) => attributes.map((attribute : Attribute) => console.log("Piping into the http-request and mapping one object after another: " + attribute.name))),
map((attributes : Attribute[]) => attributes.map((attribute : Attribute) => new Attribute(attribute.id, attribute.name, attribute.title, attribute.description,
(attribute.parameters ? attribute.parameters.map((parameter : Parameter) => new Parameter(parameter.id,
parameter.name, parameter.value)) : [])))));
}
My problem running the application at this point is the 'to-create-on-stream' Attribute
-objects and "nested" Parameters[]-array (created by pushing Parameter
-objects into it) pushed into the _attributes
-array from the httpClient's Observable: Piping into the http-request and mapping one object after another: undefined
.
Apart from this - is my construct the right way to read values from a JSON-file (or alternatively an API-stream, which may change while a user visits the SPA) into properties of multiple objects displayed on the Angular view?
With the answer mentioned above - or the way I thought I have to translate it into my code - I start to doubt that I'm really understanding (and using) the reactive Angular way with Data-Providers <= Observables => Operators => Subscribers and finally Observers displayed to the user.
I really am confused (as you can read), because a lot of answers and descriptions that I found so far use either older patterns (before Angular 5.5?) and/or partially contradict each other.
Do I handle the API-changes in the right place? Has the array for the template's *ngFor
-directives to be an Observer (handled with | async
) or will the changes of respectively within the array be handled by the model behind the template and the template grabs its new values (with interpolation and property binding) and also directives with a change in the components properties without async
ing?
Briefly: Is there a for-dummies default instruction to "stream-read" values from a http-request into multiple Typescript-objects and their properties concurrently displayed in a template with on-stream-changing directives rendered only in the relevant DOM nodes, the Angular 8 opinionated way? "Stream-reading" meaning: pulling and pushing (only) if there are changes in the API, without wasting resources.