How to share application level data between pages in Angular 2+

287 views Asked by At

Like many, I have involved in quite a few Angular projects, both the older 1.x and new 2+ (currently it is version 4). One of the issues I frequently deal with in those projects is that the sharing of the application level data between different pages.

There are a few ways of doing this, such as using a service and injecting it in the different pages that use the same data. Also, I have seen some projects that used the local storage to persist common data so that other pages that can go there and retrieve it whenever they need to.

Recently, I wanted to come up with a better solution: I simply introduced a base page with an injected data service so that I can share the data accordingly in the sub-classes. In other words, the injection is done at the base class only (i.e. no need to inject the service for every single page). In order to do that however, I have to hold a reference in a static data member within the base class. In this case, if I get an injected data service in the constructor I save it to the static member, if not, I try to initialize the class instance with the static data member's value. Now, I have the injected data in the base class and I am able to access it from the sub-classes. This works very well and I am happy with it.

Here are the sample code snippets:

// Shortened for the sake of simplicity
@Component({
    selector: 'base-page',
    templateUrl: "./index.html",
    styleUrls: [ "./index.scss" ],    
})
export class BasePage implements OnInit {
    static dataService: DataService;

    constructor(public dataService?: DataService) {
        console.log("dataService", dataService);

        if (dataService) {
            // Just make sure to include the base-page in the 
            // main html page of your app (i.e. <base-page></base-page>) 
            // Now the service will be injected and we have a 
            // chance to get the reference to it.
            console.log("Data service is set in the BasePage");
            BasePage.dataService = dataService;
        }
        else {
            // This sets the class instance with the value from the 
            // static data member of this class.
            // Now, the dataService is accessible from the 
            // subclasses...
            this.dataService = BasePage.dataService;
        }        
    }   

    ngOnInit() {
        console.log("Hello BasePage");
    }
}

// ...
// Shortened for the sake of simplicity
@Component({
    selector: 'home-page',
    templateUrl: "./index.html",
    styleUrls: [ "./index.scss" ],    
})
export class HomePage extends BasePage implements OnInit {

    constructor() {
        super();

    }

    ngOnInit() {
        console.log("Hello HomePage");
        console.log("Data", this.dataService.appLevelData);
    }
}

I was wondering if anyone else tried a similar approach? What is your favorite way of sharing the common data among different pages in your applications?

I am eager to see your reactions and I believe the answers to this question from different developers may tremendously help other developers as well.

Thanks in advance.

1

There are 1 answers

0
Socal Coder On

I always inject the services in the constructors, but I see your point. I will give it a try.