I have multiple directives combined in the same view, all accessing the same Angular $resource. One of the directives contains a form.
I would expect $resource to return a singleton so any change in the data would be reflected automatically in all the other directives, but this is not the case.
See a codepen with an example. See also the code below:
angular
.module("app", ["ngResource"])
.controller("c1", function($scope, res) {
$scope.response = res.get();
})
.controller("c2", function($scope, res) {
$scope.response = res.get();
})
.service("res", function($resource) {
const url = "https://httpbin.org/delay/1";
return $resource(url, {
get: { method: "GET" },
save: { method: "POST" }
});
});
<div ng-app="app">
<div ng-controller="c1">
c1: {{response.origin}}
</div>
<div ng-controller="c2">
c2: {{response.origin}}<br>
<input width="200" ng-model="response.origin" style="width: 300px;" /><br>
</div>
</div>
I would expect any change in the input box to be updated in both views ($scope.response should point to the same object), but only the one under the same isolated scope is changed.
Is there a way to share the same $resource object among views?
One way to do this is to keep the $resource inside the service and only access it via service methods. See https://codepen.io/miki/pen/xoVoap. You have to be careful with this approach as the singleton will be updated with the parameters passed every time it is called. So this works well for cases when the resource is unique.
angular
.module("app", ["ngResource"])
.controller("c1", function($scope, srv) {
$scope.srv = srv;
$scope.srv.get("https://httpbin.org/delay/1");
})
.controller("c2", function($scope, srv) {
$scope.srv = srv;
$scope.srv.get("https://httpbin.org/delay/1");
})
.service("srv", function($resource) {
let service = {};
service.get = url => {
service.$resource = $resource(url, {
get: { method: "GET" },
save: { method: "POST" }
});
service.resource = service.$resource.get();
};
return service;
});
The HTML:
<div ng-app="app">
<div ng-controller="c1">
c1: {{srv.resource.origin}}
</div>
<div ng-controller="c2">
c2: {{srv.resource.origin}}<br>
<input width="200" ng-model="srv.resource.origin" style="width: 300px;" /><br>
</div>
</div>