Share bound data

39 views
Skip to first unread message

mark goldin

unread,
Sep 24, 2014, 12:35:53 PM9/24/14
to ang...@googlegroups.com
I have UI that is bound to some $scope values. When I go deeper into my application I need to use values entered in UI. At some point data that was put on $scope by UI is not available. How can I share data collected from UI across the app?

Thanks

Mark Volkmann

unread,
Sep 24, 2014, 12:41:28 PM9/24/14
to ang...@googlegroups.com
One way to do that is to put the data in a service and inject that service everywhere you need it. For example,

myModule.factory('myDataSvc', function () {
  var svc = {};
  var favoriteNumber;

  svc.setFavoriteNumber = function (n) { favoriteNumber = n; };
  svc.getFavoriteNumber = function () { return favoriteNumber; };

  return svc;
}

On Wed, Sep 24, 2014 at 11:35 AM, mark goldin <markz...@gmail.com> wrote:
I have UI that is bound to some $scope values. When I go deeper into my application I need to use values entered in UI. At some point data that was put on $scope by UI is not available. How can I share data collected from UI across the app?

Thanks

--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to angular+u...@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/d/optout.



--
R. Mark Volkmann
Object Computing, Inc.

mark goldin

unread,
Sep 24, 2014, 12:43:41 PM9/24/14
to ang...@googlegroups.com
And that is what I kind of have. But my problem is that UI is bound to $scope. When I select a new vlaue that value is not getting into myDataSvc.

--
You received this message because you are subscribed to a topic in the Google Groups "AngularJS" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/angular/dkXHM4dufvw/unsubscribe.
To unsubscribe from this group and all its topics, send an email to angular+u...@googlegroups.com.

Mark Volkmann

unread,
Sep 24, 2014, 12:47:55 PM9/24/14
to ang...@googlegroups.com
You could watch the scope property for changes and then pass the new value to the setFavoriteNumber method of the service. Something like this:

$scope.$watch('myScopeProp', myDataSvc.setFavoriteNumber);

mark goldin

unread,
Sep 24, 2014, 12:50:31 PM9/24/14
to ang...@googlegroups.com
Where would I watch? Right in myDataSvc?

mark goldin

unread,
Sep 24, 2014, 3:39:23 PM9/24/14
to ang...@googlegroups.com
I dont see myDataSvc.setFavoriteNumber being called when myScopeProp is changed. How can I debug it?

Thanks

Mark Volkmann

unread,
Sep 24, 2014, 3:51:53 PM9/24/14
to ang...@googlegroups.com
No. Set up the watch in your controller where you have access to $scope. Inject the service into that controller so you can call your equivalent of setFavoriteNumber in the watch callback function.

mark goldin

unread,
Sep 24, 2014, 3:55:15 PM9/24/14
to ang...@googlegroups.com
That is exactly what I am doing, but "equivalent of setFavoriteNumber " is not getting called.

Mark Volkmann

unread,
Sep 24, 2014, 3:58:31 PM9/24/14
to ang...@googlegroups.com
Show me your call to $scope.$watch.

mark goldin

unread,
Sep 24, 2014, 4:02:27 PM9/24/14
to ang...@googlegroups.com
$scope.eventDateFrom = getFormattedDate(date);
localData.add("eventDateFrom", $scope.eventDateFrom); // Will properly store key and value.

$scope.$watch("eventDateFrom", localData.add("eventDateFrom", $scope.eventDateFrom)); // will not trigger localData.add


Mark Volkmann

unread,
Sep 24, 2014, 4:16:36 PM9/24/14
to ang...@googlegroups.com
Do you have an input in your HTML with ng-model="eventDateFrom"?
When you change the value of the input by typing a new value in the browser, does the watch get triggered?
Oh, I think I see the problem. You need to pass a function to $watch like this:

$scope.$watch('eventDateFrom', function (value) {
  localData.add('eventDateFrom', value);
});

mark goldin

unread,
Sep 24, 2014, 4:33:56 PM9/24/14
to ang...@googlegroups.com
Nope, does not look like it works. With my version it gets into  localData.add when a view is loading. But with yours is not getting there at all.

Mark Volkmann

unread,
Sep 24, 2014, 4:36:16 PM9/24/14
to ang...@googlegroups.com
Add a console.log inside the callback function for the watch to verify whether that is getting triggered. It seems like the ng-model isn't getting configured correctly.

If that doesn't help, I suggest creating a plunk that demonstrates the problem.

Eric Eslinger

unread,
Sep 24, 2014, 4:40:14 PM9/24/14
to ang...@googlegroups.com
Also, try putting a dot in your model. As in, instead of looking at $scope.value, do $scope.view.value

Angular in the past at least, had issues with watching primitive types on the scope.

mark goldin

unread,
Sep 24, 2014, 5:01:23 PM9/24/14
to ang...@googlegroups.com
Not sure I understand, So, instead of ng-model="eventDateFrom" I should say ng-model="data.eventDateFrom"?

Eric Eslinger

unread,
Sep 24, 2014, 5:03:03 PM9/24/14
to ang...@googlegroups.com
yeah. That's because child scopes use prototype inheritance to reference parent scope data.

e

mark goldin

unread,
Sep 24, 2014, 5:47:24 PM9/24/14
to ang...@googlegroups.com
And that is my problem. $scope is going out of scope when I move to child state. So, instead of trying to work around it how can I make it available everywhere?

Mark Volkmann

unread,
Sep 24, 2014, 6:00:47 PM9/24/14
to ang...@googlegroups.com
There are many ways to do what you are asking.

One way is to put the data on the root scope by injecting $rootScope or using $scope.$root. That is frowned upon.

Another way is to explicitly work with the data on the parent scope like this:
$scope.$parent.foo = 'bar';
That's also somewhat frowned upon.

Another way is for the parent to create an object that will hold data that is accessed when the scope hierarchy is traversed. The controller for the parent could do this:

$scope.holder = {};

The controllers for any descendant scopes could then do this:

$scope.holder.foo = 'bar';
and
var foo = $scope.holder.foo;

This is really just taking advantage of the dot that Eric Eslinger suggested. It works when the descendant scopes don't have a property named "holder" and traversing the hierarchy finds it in an ancestor scope.

Another way is to use a shared service that is injected into all the controllers that need it.

mark goldin

unread,
Sep 24, 2014, 6:05:58 PM9/24/14
to ang...@googlegroups.com
What exactly is shared service?

mark goldin

unread,
Sep 24, 2014, 6:07:17 PM9/24/14
to ang...@googlegroups.com
What exactly is shared service?

Mark Volkmann

unread,
Sep 24, 2014, 6:13:51 PM9/24/14
to ang...@googlegroups.com
By "shared service" I mean a normal AngularJS service that is injected into multiple places. Only one instance will be created and all the places where it is injected share that instance.
Reply all
Reply to author
Forward
0 new messages