sharing data between controllers, ionic + angular js - angularjs

these are my controllers:
.controller('recommendedJobsCtrl', function($q,$scope, $ionicSideMenuDelegate,$window,$http,dataShare) {
$scope.text='hey world';
$scope.post=function(){
dataShare.sendData($scope.text);
console.log('sent: ' + $scope.text);
}
})
.controller('jobsCtrl', function($scope,dataShare) {
$scope.words=dataShare.getData();
})
and this is my factory:
.factory('dataShare',function($rootScope){
var service = {};
service.sendData = function(data){
service=data;
$rootScope.$broadcast('data_shared', service);
},
service.getData = function(){
console.log('this.data is ' + service)
return service;
};
return service;
});
when the console.log prints, service is empty. How do i fix this ?

Factory code is not written correctly and also you should use angular service instead of creating factory since you have to only share data between controllers. Although both are singleton objects.
Lets do it with factory first
.factory('dataShare',function(){
var service = {
sendData: sendData,
getData: getData
};
var serviceData;
function sendData(data){
serviceData = data;
}
function getData(){
console.log('this.data is ' + serviceData);
return serviceData;
}
return service;
});
Lets do it with service
.service('dataShare',function(){
var serviceData;
this.sendData = function(data){
serviceData = data;
}
this.getData = function(){
console.log('this.data is ' + serviceData);
return serviceData;
}
});

To receive data you need to :
$rootScope.$on('data_shared', function(evt, data) {
});
It is async operation, so you cannot invoke it synchronously. If you want to abstract the communication, you need to implement you own observer/subscriber pattern.

Related

I get 'is not a function' Error when calling Factory method from controller in angular.js

I'm trying to call a factory method in angular.js from my controller method and it throws an error 'is not a function'
Here's how the factory looks:
function getData($q) {
var getMessages = function(id) {
var deferred = $q.defer();
// deferred.notify('About to greet ' + name + '.');
GTS2_FIN_MU_Dist_Pct_Controller.getUltimates(
id,
function(result, event) {
if (event.status) {
// console.log(result);
var obj = JSON.parse(result);
deferred.resolve(obj);
} else {
deferred.reject("Error Processing the Request : " + event.message);
}
},
{ escape: false }
);
return deferred.promise;
};
return {
getMessages: getMessages,
};
}
app.factory("getData", getData);
The controller looks like:
app.controller("intlMassUpdateDistPctController", function($scope)
{ // define angular controller
$scope.ultimates = new Array; // define empty array to hold ultimate versions from VF remote action
// Calls controller method Remote Action and passes the ultimateId, and handles the result by storing it inside $scope.ultimateVersions
$scope.loadData = function(){
//$j214('#dialogNew').show();
var promise = getData.getMessages(''); //Calling factory method.. This is where U get the error
promise.then(function(obj) {
$scope.selectedForecastLocked = false;
var JSONdata = JSON.parse(obj);
$scope.ultimates = JSONdata.Ultimates;
$scope.gridOptions.api.setRowData($scope.ultimates);
........
}, function(reason) {
alert('Failed: ' + reason);
}, function(update) {
alert('Got notification: ' + update);
});
}
});
I have also defined the app.
var app = angular.module('intlMassUpdateDistPct', ['agGrid','ui.bootstrap']);
And Finally:
<body ng-app="myApp" >
<div ng-controller="intlMassUpdateDistPctController">
Can someone please help me identify what's missing.
Try to inject getData factory in the controller :
app.controller("intlMassUpdateDistPctController", function($scope,getData){
// your code...
})

angular factory gives Error: [$injector:undef]

Factory looked so simple, but I have no idea what this error is?!?
When my controller calls ReportData.add I get
Error: [$injector:undef]
app.factory('ReportData', function() {
var factoryData = [];
var factoryService = {};
factoryService.add = function(myData) {
console.log('FACTORY ADD: ' + myData)
factoryData = myData;
};
factoryService.get = function() {
console.log('FACTORY GET: ' + factoryData)
return factoryData;
};
});
app.controller("test", function ($scope, $http, $location, ReportData) {
ReportData.add('SENDING DATA TO FACTORY');
console.log('get it: ' + ReportData.get());
})
You're not returning the object at the end of the function, this is why angular is unable to inject the factory.
When you inject the factory angular look for all the registered factories, then executes the corresponding function (only once) and cache the returning object that is the same object that angular will inject inside your controller.
If you don't return anything inside the function angular is not able to resolve your dependency.
app.factory('ReportData', function() {
var factoryData = [];
var factoryService = {};
factoryService.add = function(myData) {
console.log('FACTORY ADD: ' + myData)
factoryData = myData;
};
factoryService.get = function() {
console.log('FACTORY GET: ' + factoryData)
return factoryData;
};
return factoryService; //you're missing this return statement
});

Angular Service doesn't return value

Im using angularjs in MVC.
Here My Controller.js:
//Get User By ID
$scope.GetUserById = function (UID) {
var Get = UserService.GetUserById(UID);
Get.then(function (response) {
$scope.User = response.data;
alert($scope.User.Address);
});
};
services.js:
//Get By ID
this.GetUserById = function (UID) {
debugger;
return $http.get("../api/UsersData/GetUserById?UID=" + UID);
};
When I'm using the debugger, the alert message is displayed. If I'm not debugging then it doesn't return a value.
What is the issue in my code?
How to display the value to html page?
You should get it working with few adjustments.
Service.js:
angular.module('myApp').factory('MyService', MyService);
//Avoid Minification Problems
MyService.$inject = [ '$http' ];
function MyService( $http ){
function GetUserById(UID){
return $http.get('../api/UsersData/GetUserById?UID=' + UID)
.then( function (response) {
if(response){
return response;
}
});
}
//Expose Method to External Calls
return {
GetUserById : GetUserById
}
}
Controller.js:
angular.module('myApp').controller('MyController', MyController);
MyController.$inject = [ '$scope', 'MyService' ];
function MyController( $scope, MyService ){
$scope.GetUserById = function(UID){
MyService.GetUserById(UID).then( function(response){
$scope.User = response.data;
alert($scope.User.Address);
});
}
}
Make sure what response is actually returning with a $log or using console.log in order to properly alert the address. Do this check also in the service, for instance you should check if response.address exists.
You can also use a Service instead of a Factory.

Angular : Share data returned from factory between controllers

I havea factory call HTTP end point to fetch user:
.factory('me', function($resource, VAS_API_URL, $q) {
return {
getUser: function() {
var deferred = $q.defer();
var url = VAS_API_URL + 'api/me';
$resource(url)
.get(function(user) {
deferred.resolve(user);
}, function(response) {
deferred.reject(response);
});
return deferred.promise;
}
};
})
I use this factory in many controllers and, i bind the data to the DOM successfully, but at times i want to use the data returned from the factory in my controller like to save the user name with a notification so i had to do the following:
.controller('createNotificationCtrl', function($scope, VAS_API_URL, me) {
var Burl = VAS_API_URL + 'api/notification';
$scope.profile = me.getUser();
$scope.profile.then(
function(user) {
$scope.owner = user;
$scope.item = {};
$scope.item.message = $scope.message;
$scope.item.owner = $scope.owner.displayName;
},
function(response) {
console.log(response);
}
);
})
I had to creat $scope.item = {}; in the factory call so i could get the displayName then send the object to save a notification but what if i want to save also another filed from another factory. How it could be done?
The factory should create the object and hold it as a state.
The controller's should use the reference from the factory and update it for everyone.
factory code sample:
this.stateObj = {};
....
....
this.getUser = function(){
var promise = $http.get(url);
promise.then(function(res){
// update stateObj
});
return promise;
}
ctrl code sample:
factory.getUser().then(function(res){
$scope.stateObj = factory.getStateObj();
});

Sharing ajax data between multiple controllers in angular using service

Hi I have two controllers
pqsAppModule.controller('NotificationBoxController',function($scope,items) {
$scope.list = items.list();
})
and
pqsAppModule.controller('NotificationController',function($scope,items) {
$scope.list = items.list();
})
I need to create an "items" service that would do an ajax request and return data for any controller which would have it injected. And I want, that the query will be done only once, and items will be shared between all controllers.
pqsAppModule.factory('items', function($http) {
var items = [];
var itemsService = {};
$http.get('api/notification').then(function(response){
items = response.data;
});
itemsService.list = function() {
return items;
};
return itemsService;
});
But I don't understand why angular makes the request, and receives data, but all items in controllers are empty.
It happens because the factory should be defined by different way.
(I took dummy URL only to load data by async way)
HTML
<div ng-controller="NotificationBoxController">
<button ng-click="showMe();">press me</button>
<pre>NotificationBoxController: {{items.getList()|json}}</pre>
</div>
<div ng-controller="NotificationController">
<pre>NotificationController: {{items.getList()|json}}</pre>
</div>
JS
var pqsAppModule = angular.module('myApp', []);
pqsAppModule.controller('NotificationBoxController',function($scope,items) {
$scope.items = items;
$scope.showMe= function(){
items.query();
}
});
pqsAppModule.controller('NotificationController',function($scope,items) {
$scope.items = items;
});
pqsAppModule.factory('items', function ($http) {
var current = {};
var address = 'Singapore, SG, Singapore, 153 Bukit Batok Street 1';
var URL = 'http://maps.googleapis.com/maps/api/geocode/json?address=' + address + '&sensor=true';
var factory = {
query: function () {
var data = $http({method: 'GET', url:URL}).then(function (result) {
current = result.data.results[0];
}, function (result) {
alert("Error: No data returned");
});
},
getList: function () {
return current;
}
}
return factory;
});
Demo Fiddle
From this example we call items.getList() from HTML for both controllers. But if we want to update the model through the controller, we need a listener like $watch
Try this
$http.get('api/notification').then(function(response){
angular.foreach(response.data,function(item) {
items.push(item);
});
});
Basically do not create a new array but fill the existing one.

Resources