Angular started off nice and easy. Magical, even. “Two-way binding! Wow!”
And you trotted off and started building your masterpiece, until you hit a snag: you’re building standalone components like everyone online suggests, but how do you share data between those components?
Maybe you have 2 views in separate routes that need access to some status variable. Or you have 3 separate components that all need access to the same piece of data.
What’s the best way to share it? Some sort of crazy controller-inheritance scheme?
No, of course not. The simple, easy way is to use a service.
Let’s say you have 2 panes, side-by-side, each represented by a directive.
Here’s the code for Pane 1:
And for Pane 2:
We want to be able to type something into the input box in Pane 1, click “Add To List”, and have it appear in Pane 2’s list.
Create a Service to Hold Shared State
In order to share data between 2 or more controllers, create a service that acts as a mediator. This keeps the controllers (or components) loosely-coupled: they don’t need to know about each other, they just need to know about the data source – your service.
This service is super simple. Call
addItem to put things in the list, and
getList to retrieve the whole list. It’s so simple, it doesn’t even support removing or clearing items. That’s how simple this thing is.
Inject That Service Everywhere That Cares
Now that we have our service, we need to inject it everywhere that needs to access or modify the data.
Start with Pane 1’s controller:
Now Pane 2’s controller, to read the data:
No Watchers Though?
As I was writing this, I was pretty sure that the list in Pane 2 would not automatically update until I added some watchers.
But then, I put the code into JSBin, and … lo and behold, it works! Why?
ng-repeatsets up a watcher on the array
- Clicking “Add To List” triggers a digest cycle, which re-evaluates the
sharedData.getList()returns a reference to an array, the watcher sees that
p2.listItemshas changed. This is crucial: if
getListreturned a different array than the one modified by
addToList, this would not work.
So: This communication method may work perfectly fine without watchers. But if you find that it isn’t, check how you’re passing data around. You may need to explicitly watch for changes.
- Create a service to contain your data. Give it getter and setter methods.
- Inject that service anywhere that needs the data.
- That’s pretty much it (unless you need watchers – in which case, add them).
Want to learn best-practices Angular development, as well as get a head start on Angular 2, ES6, and TypeScript? Sign up for my newsletter below!
Thanks for reading.
Learning React can be a struggle -- so many libraries and tools!
My advice? Ignore all of them :)
For a step-by-step approach, read my book Pure React.