Sharing Data Between Controllers

AngularJS Video Tutorial by

Enter Your Email Address to Watch This Lesson

Your link to unlock this lesson will be sent to this email address.

Unlock this lesson and all 191 of the free egghead.io lessons, plus get AngularJS content delivered directly to your inbox!



Existing egghead subscribers will not see this. Sign in.

Just one more step!

Check your inbox for an email from us and click link to unlock your lesson.




Edit

Sharing Data Between Controllers

3:19 AngularJS lesson by

If AngularJS Controllers are the glue of an application, how do they communicate and pass data around? This introduction to service factories will shed some light on that question.

Find the code for this lesson on JSBin.

egghead.io comment guidelines

egghead.io
Avatar

If AngularJS Controllers are the glue of an application, how do they communicate and pass data around? This introduction to service factories will shed some light on that question.

Mark
Avatar

How would you use this approach with dynamic data?

I have data being added to a collection within the service factory using $http. I'm using one controller to initiate the request and than use $q.defer().resolve() to adjust its $scope, but the second controller that shares the same service doesn't update when the services data changes.

Joel
Avatar

I'd need to see the code but my guess is that you are completely overwriting the property with a new object. You want to update the object/array and not replace to allow binding to function.

Instead of using ngController on an element, it's actually preferred to use one controller per state. To use states we need to grab Angular UI routers. We'll copy it from a CDN and then simply paste it into our project.

To use UI router we need to add it to our list of dependencies, UI.router. Then, since we're going to be writing some more code, let's move this out to a separate script file. I'll cut this, create a new file called app.JS, and paste the code I had in there. Our application should still be working just fine.

To add a state for our controller we say, ".config" which allows us to configure our application before it boots up. We'll add a function called config which we're just naming for debugging later and add something called state provider, which is what we add our states to.

We'll say "stateprovider.state" and add a state of index. Now the second parameter here is a configuration object which takes a URL which will simply be nothing for now, a controller which will be first controller as first which should look familiar, first being how we will reference it in our HTML and first controller maps to the controller we created here, and then a template URL which is a template which we will load in.

We'll say, "templatesfirst.html." To create this template we'll switch over to our project view, create a new HTML file inside of the templates directory, and then I'll delete all this boiler plate code. We don't need that. Copy and paste all of this code, so cut it out and paste it in here.

Inside of our index we don't need this anymore, because that's referenced inside of our state and configured there. All we need is to say, "Use UI view," and place whatever template we've configured right on that UI view element and use the state provider to configure and provide that data.

Now our application is right back to where it was before, still working, but now our states are configured inside of a configure function and it's mapping a controller to a template where first controller is defined here and first is used inside of our template in each of those same positions.

This means that sharing data between controllers is essentially sharing data between states or templates. Let's create another template to pass some data into. We'll call this template second and just simply have it be an H1 with some binding in it that says second.greeting.message.

Now we need to create a state for this template by simply duplicating this line. We'll call this state second, give it a URL of second, rename this to second control, rename these guys to second. Then we need to create a second controller which we'll do by duplicating this and, again, renaming this to second and renaming these guys to second.

Now we have a second state with a second controller. To navigate to this URL in our first template, we'll just say div ui-sref which means, "Take us to this state when we click on it." We'll say, "Go to second." Now clicking on "go to second" will take us to a blank page because in our second template there's no data for this message.

To set this up and share data between controllers or states or templates or whatever you want to say, we'll create a service. We'll call this service greeting. We'll give it a named function of greeting. In this scenario this greeting is being treated like a constructor and returning an instance, so we're going to call it lower case. Some people call services upper case. It just depends on who you talk to, but we'll, for convenience, set up greeting as this in case of scoping issues later and say, "greeting.message equals default."

Now to share him between controllers, all we have to do is add him and here. We'll type greeting. Similarly for here and here instead of first we can say greeting. This gives us the same greeting object or service on each controller with a message property which we can bind to from each controller.

We already added message in our second template. Let's go ahead and do that in this first template. I'll find all the greetings and change it to greeting.message. Now if I run this and change it from default, again, it says default because the default message is default, if I change it to hi and click "go to second," you will see the message we get is hi.