AngularJS factory for sharing data between controllers - javascript

I have an AngularJS application (1.4.10) and I need to share some data between two controllers.
So I made my factory:
.factory('CardsForService', function($http, URL){
var service = {
"block_id": '',
"service_id": ''
};
service.save_data = function(block_id, service_id){
service.block_id = block_id;
service.service_id = service_id;
};
service.get_data = function(){
return service;
};
return service;
})
I insert the data in the first controller:
$scope.open = function(id, type){
console.log(id +" "+type);
CardsForService.save_data(id, type);
...
And I try to get the data in another controller, like this:
$scope.$on('$routeChangeSuccess', function() {
if (algo_to_used == "service"){
var data = CardsForService.get_data();
console.log(data);
} else {
}
});
The console.log output this:
Object {block_id: "", service_id: ""}
If I try the same get_data() function in the same controller where I call the save_data() function I have the correct results.
What am I missing?

Change Factory Like this
app.factory('CardsForService', function(){
var service = {
"block_id": '',
"service_id": ''
};
var save_data = function(block_id, service_id){
service.block_id = block_id;
service.service_id = service_id;
};
var get_data = function(){
return service;
};
return{
saveData:save_data,
getData:get_data
}});
And in controllers
app.controller('FirstCtrl',function(CardsForService){
CardsForService.setData(id, type);
});
app.controller('SecondCtrl', function($scope, CardsForService){
$scope.data = CardsForService.getData();
});

This sounds like it could be a timing issue. Data from a service like this isn't reactive. Here's a snippet that should help visualize it.
var app = angular.module("demo", []);
app.factory("MySvc", function() {
var data = {};
data.setData = function(key, value) {
this[key] = value;
}
data.getData = function(key, def) {
return key in this ? this[key] : def;
};
return data;
});
app.controller("test1", ["$scope", "MySvc", "$timeout",
function($scope, MySvc, $timeout) {
$timeout(100).then(function() {
MySvc.setData("foo", "bar");
$scope.data = MySvc.getData("foo");
});
}
]);
app.controller("test2", ["$scope", "MySvc", "$timeout",
function($scope, MySvc, $timeout) {
$timeout(500).then(function() {
$scope.data = MySvc.getData("foo", "baz");
});
}
]);
app.controller("test3", ["$scope", "MySvc",
function($scope, MySvc) {
$scope.data = MySvc.getData("foo", "asdf");
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js "></script>
<div ng-app="demo">
<pre ng-controller="test1">Test 1: {{ data }}</pre>
<pre ng-controller="test2">Test 2: {{ data }}</pre>
<pre ng-controller="test3">Test 3: {{ data }}</pre>
</div>

Ok I solved the problem. Basically before I was using this code for the redirect to the new page:
$window.location.assign('/cards/service');
And now I switched to this code:
$location.path('/cards/service');
And it's working.
The only thing is that when it wasn't working when I redirect the page the console in the chrome inspector refresh for every reloading, now the console do not refresh. Can someone tell me the difference between those two functions?

Related

Pass data between functions in same controller using another service to get data

I get some data through Myservice from another Controller. I can see {{users.data}} from the view, but users.length = 0 ,and $data is empty, that means I can't access to the content of MyService in getData function.. if i replace MyService with json data like
$scope.users=[{..},{..}] it works fine
thank you ..
app.service('MyService', function() {
return data = [];
});
app.controller('tableController', function ($scope,
$filter,NgTableParams,MyService) {
$scope.users= MyService
$scope.usersTable = new NgTableParams({
page: 1,
count: 6
}, {
getData: function(params) {
params.total($scope.users.length);
$scope.da = params.sorting() ? $filter('orderBy')
($scope.users, params.orderBy()) : $scope.da;
$scope.da= params.filter() ? $filter('filter')
($scope.da, params.filter()) : $scope.users;
return $scope.da.slice((params.page() - 1) *
params.count(), params.page() * params.count());
}
}
);
});
When you get your data in the first controller you call MyService.setData(data); The service will store in its local var data and keep it there. Then in the second controller you can retrieve that data by calling MyService.getData()
app.service('MyService', function() {
var ret = {
data: [],
setData: function(inData) {
ret.data = inData;
},
getData: function() {
return ret.data;
}
};
return ret;
});
the first controller 1
app.controller('EventCtrl', ['$scope', 'EventService', 'MyService',
function ($scope, EventService , MyService) {
var baseUrl = '';
$scope.getEvents=function()
{
var apiRoute = 'http://localhost:9811/notification/notification/';
var _Event = EventService.getAll(apiRoute);
_Event.then(function (response) {
$scope.events= response.data;
MyService.data = $scope.events;
MyService.setData($scope.events);
$scope.VarCtrl1= MyService;
},
function (error) {
console.log("Error: " + error);
});
}
$scope.getEvents()
}]);
i updated the service but it doesnt work ..so i modified the first controller like this what do you think?
app.controller('EventCtrl', ['$scope', 'EventService', 'MyService',
function ($scope, EventService , MyService) {
var baseUrl = '';
$scope.getEvents=function()
{
var apiRoute =
'http://localhost:9811/notification/notification/';
var _Event = EventService.getAll(apiRoute);
_Event.then(function (response) {
var data = response.data
MyService.setData(data);
$scope.VarCtrl1= MyService;
},
function (error) {
console.log("Error: " + error);
});
}
$scope.getEvents()
}]);
Thanks for the update of the service now its better ...i can have data in $users and $data in tableController but orderBy need an array but i get this :( when i do consoleLoge($scope.users)
Object {data: Array(0), setData: function, getData: function}data:
Array(9)0: Object1: Object2: Object3: Object4: Object5: Object6:
Object7: Object8: Objectlength: 9__proto__: Array(0)getData:
function ()setData: function (inData)proto: Object
tableController.js:24

Using data from one controller in another

I am making a website based on MEAN. Now I am trying to pass data from one controller to the next, but I don't seem to get it done. When an option is selected I want to take this value to the next page
This is the page with the selectbox:
<div class="plumber-by-city col-sm-12 home-text-col" ng-controller="DataCtrl">
<div class="title-1">Search by cityname</div>
<select ng-model="selectedItem" ng-change="change()" ng-options="item as item.city for item in items"></select><span class="fa fa-caret-down"></span>
</div>
On change I want to take the selectedItem passed through to the next page with DataCtrl2
This is my DataCtrl:
app.controller('DataCtrl', function($scope,$http,getData,$location,$routeParams){
getData.getCity($scope);
$scope.change = function() {
$location.path('/plumber-in/' + $scope.selectedItem.city);
};
});
And the service that retrieves data from DB:
app.factory('getData', function($http){
return {
getCity: function($scope){
return $http.get("/getdata").then(function(response){
$scope.items = response.data;
$scope.selectedItem = response.data[0];
});
}
};
});
Now I don't know what to put in the DataCtrl2 for the second page and how to use the data from the DataCtrl in this page
What you need is a Setter and Getter Method in your service. Something like this
app.controller('DataCtrl',
function($scope,$http,getData,$location,$routeParams){
getData.getCity().then(function(response) {
$scope.items = response.data;
$scope.selectedItem = response.data[0];
});
$scope.change = function() {
// sets the data to the service
getData.setItem($scope.selectedItem);
$location.path('/plumber-in/' + $scope.selectedItem.city);
};
});
app.factory('getData', function($http){
return {
getCity: function(){
return $http.get("/getdata");
},
setItem: function(item) {
this.item = item;
},
getItem: function() {
return this.item;
}
};
});
app.controller('DataCtrl2',
function($scope, $http, getData,$location,$routeParams){
// get the data from the service
getData.getItem();
});
don't use $scope inside the factory. just return the request-promise to the controller and do your logic in there.
app.factory('getData', function($http){
return {
getCity: function(){
return $http.get("/getdata");
}
};
});
modify the controller like this
app.controller('DataCtrl', function($scope,$http,getData,$location,$routeParams){
getData.getCity().then(function(response) {
$scope.items = response.data;
$scope.selectedItem = response.data[0];
});
$scope.change = function() {
$location.path('/plumber-in/' + $scope.selectedItem.city);
};
});

Pass value from provider to controller in angularJs

I'm trying get data from db to UI. Url given via provider is getting the data.
Controller in controller DetailsProvider.getDashboardDetails() is getting null.
var appmod = angular.module('project.DetailDashboardController', []);
appmod.controller("DetailDashboardController", ['$rootScope', '$scope', '$state', 'DetailsProvider',function($rootScope, $scope, $state,DetailsProvider) {
console.log("DetailDashboardController --- ");
$scope.DetList= DetailsProvider.getDashboardDetails()
}]);
})(window, window.angular);
provider which will call the list
(function(angular) {
var appmod = angular.module('project.DetailsServiceProvider', []);
appmod.provider('DetailsProvider', function() {
this.$get = ['_$rest', function DetailServiceFactory(_$rest) {
return new DetailsProvider(_$rest);
}];
});
function DetailsProvider(_$rest) {
this._$rest = _$rest,
this.getDashboardDetails = function(_callback, _data) {
var newData = null;
_$rest.post({
url: window.localStorage.getItem('contextPath') +'home/listdetail',
data: {} ,
onSuccess:_callback
}
});
}
};
})(window.angular);
Thanks in advance for any kind of reply!
You should return promise from your service method and do thenable in your controller.
Root Cause : your are returning the newData which will initalized later after completing the ajax call.Before completing it,you are returning the same variable which will be always null.
In provider,
(function(angular) {
var appmod = angular.module('project.DetailsServiceProvider', []);
appmod.provider('DetailsProvider', function() {
this.$get = ['_$rest', function DetailServiceFactory(_$rest) {
return new DetailsProvider(_$rest);
}];
});
function DetailsProvider(_$rest) {
this._$rest = _$rest,
this.getDashboardDetails = function(_callback, _data) {
var newData = null;
_$rest.post({
url: window.localStorage.getItem('contextPath') +'home/listdetail',
data: {} ,
onSuccess:_callback
}
});
}
};
})(window.angular);
and in controller,
$scope.list = function() {
DetailsService.getDashboardDetails(function(data){
varr holdIt = data.data.DList;
});
};

AngularJS set var: http get

I have an angular filter set up which works great:
categorieFilter = angular.module("categorieFilter", [])
categorieFilter.controller("catFilter", ["$scope", "store", function($scope, store){
$scope.search = "";
$scope.products = [];
$scope.categories = [];
$scope.categories = store.getCategories();
$scope.products = store.getProducts();
$scope.filterProductsByCats = function(category){
$scope.search = category;
};
}])
categorieFilter.factory('store', function(){
var categories = ['Lattes','CC Blend','Frappes'];
var products = [
{name: 'Latte machiatto',category: 'Lattes'},
{name: 'Frappe ice',category: 'Frappes'},
{name: 'Latte caramel',category: 'Lattes'},
{name: 'Frappe speculoos',category: 'Frappes'},
{name: 'Cappucino',category: 'CC Blend'},
{name: 'Filter coffee',category: 'CC Blend'},
];
return {
getCategories : function(){
return categories;
},
getProducts : function(){
return products;
}
};
});
But the var categories and var products are still hard coded so I want to retreive the needed data from my server to fill these variables. And I can't seem to get this right? I have another function where I can get the required data but I don't know how I can get these 2 in 1...?
categories = angular.module('categories', []);
categories.controller("category",function($scope, $http){
var serviceBase = 'api/';
$http.get(serviceBase + 'categories').then(function (results) {
$scope.categories = results.data;
for(var i = 0; i < $scope.categories.length; i++){
var categories = $scope.categories[i];
}
});
});
So how can I properly set the var categories to the required $http.get to retreive my server data into the filter above?
I think you should be able to get rid of the hard coded block in the service and just return:
return {
getCategories: $http.get('/categories').success(function (data) {
return data;
}),
getProducts: $http.get('/products').success(function (data) {
return data;
})
}
Make sure you dependencies are setup correctly for the service though (i.e. $http):
.factory('store', function ($http) {
// The above return block here
});
And this should do the trick!

Angularjs: Promises

I'm doing some small exercises to learn AngularJS, trying to understand how to work with promises at the moment.
In the following exercise, I'm trying to get some data async. I can see the data in the console.log but the promise is returned NULL.
GET /entries 200 OK
Promise is resolved: null
Anyone experienced can give me some advice to understand what I'm doing wrong ? Thanks for looking!
angular.module('questions', [])
.config(function($routeProvider) {
$routeProvider
.when('/', {
controller: 'MainCtrl',
resolve: {
'MyServiceData': function(EntriesService) {
return EntriesService.promise;
}
}
})
})
.service('EntriesService', function($http) {
var entries = null;
var promise = $http.get('entries').success(function (data) {
entries = data;
});
return {
promise: promise,
all: function() {
return entries;
}
};
})
.controller('MainCtrl', ['$scope', 'EntriesService', function($scope, EntriesService) {
console.log('Promise is resolved: ' + EntriesService.all());
$scope.title = "Q&A Module";
$scope.entries = EntriesService.all() || [];
$scope.addMessage = function() {
$scope.entries.push({
author: "myAuthor",
message: $scope.message
});
};
}]);
/****** Thanks everyone for your help so far *****/
After taking the advice of #bibs I came up with the following solution, that's clear using ngResource:
angular.module('questions', ['ngResource'])
.factory('EntriesService', function($resource){
return $resource('/entries', {});
})
.controller('MainCtrl', ['$scope', 'EntriesService', function($scope, EntriesService) {
$scope.title = "Q&A Module";
$scope.entries = [];
EntriesService.query(function(response){
$scope.entries = response;
});
$scope.addMessage = function() {
$scope.entries.push({
author: "myAuthor",
message: $scope.message
});
};
}]);
You should access the data in the callback. Since entries maybe empty before the data arrives, the all() function is not quite useful in this case.
Try this, you should be able to chain then() method to synchronously get data.
.service('EntriesService', function ($http) {
var services = {
all: function () {
var promise = $http.get('entries').success(function (data) {
entries = data;
}).error(function (response, status, headers, config) {
//error
});
return promise;
},
someOtherServices: function(){
var promise = ....
return promise;
}
return services;
}
});
$scope.entries = [];
EntriesService.all().then(function(data){
$scope.entries = data;
});
If you want the data returned by the server to be immediately reflected in your view:
.service('EntriesService', function($http) {
var entries = [];
var promise = $http.get('entries').success(function (data) {
for (var i = 0; i < data.length; i++) {
entries[i] = data[i];
}
});
return {
promise: promise,
all: entries
};
})
.controller('MainCtrl', ['$scope', 'EntriesService', function($scope, EntriesService) {
$scope.title = "Q&A Module";
$scope.entries = EntriesService.all;
$scope.addMessage = function() {
$scope.entries.push({
author: "myAuthor",
message: $scope.message
});
};
You may want to check out $resource to do this for you: http://docs.angularjs.org/api/ngResource.$resource

Categories