1

In my angular application, I have the following array of objects:

public data = [
{a: 0, b: [{q: 1, z: 2}]}
{a: 1, b: [{q: 4, z: 9}]}
]

Question: How can I subscribe to any changes in the array (also including changes in nested objects)?

Expected result: A function that fires every time data is changed

3
  • Create a state to wrap data, export an Observable<?> that others can observe, if changes to data are happening fire that observer. Commented Nov 3, 2020 at 10:43
  • Sweet, can you show me how this is done? Commented Nov 3, 2020 at 10:46
  • How exactly will you be changing data? Commented Nov 3, 2020 at 11:12

1 Answer 1

2

First you need a service to wrap your state (here you can also use more sophisticated frameworks like Redux but lets keep it simply for the start), this is usually a good idea to decouple your application

state.service.ts

import {BehaviorSubject, Observable} from "rxjs/index";
import {Injectable} from "@angular/core";


@Injectable({
    providedIn: 'root',
})
export class StateService {

    private readonly subject: BehaviorSubject<any> = new BehaviorSubject({});

    public readonly observable: Observable<any> = this.subject.asObservable();

    public set(newValue: any): void {
        this.subject.next(newValue);
    }
}

then your component can register to observable to render it e. g. by using

public readonly value: Observable<any> = this.stateService.observable
    .pipe(map(_ => JSON.stringify(_)));

and to e. g. print out the value

<p *ngIf="value | async">{{(value | async)}}</p>

and if you are now using set to update the state the component will be refreshed automatically.

In general I found Angular applications are way easier to understand if your components and your application state are properly separated (remember Model-View-Controller?) so that your components do not contain any state themselves and are only binding the templates to the state via observables so that you do not need to care about refreshes and updates (remember Java Swing listeners?). And the state has a clearly defined interface to be interacted with so that no one fiddles in the internal structure of your application state.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for providing an example! I don't see this will fire a function if data is changed, i.e data[0].b[1] = 8
That's what I wrote with "and if you are now using set to update the state the component will be refreshed automatically." - using a pattern like mine you will not change data in any way but via methods on the state because otherwise you will not be able to observe changes on the underlying data.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.