angularJS service not getting called - angularjs

I'm very new to AngilarJS. I am trying to write a service in angularJS.
<script>
var module = angular.module("myapp", []);
module.service('BrandService', function ($http) {
var brands = [];
this.getBrands = function()
{
return $http.get('http://admin.localhost/cgi-bin/brand.pl')
.then(function(response)
{
brands = response.brands;
alert (brands);
});
}
//simply returns the brands list
this.list = function ()
{
return brands;
}
});
module.controller("brandsController", function($scope, BrandService) {
$scope.brandlist = BrandService.list();
alert ($scope.brandlist);
});
</script>
The statement "alert (brands);" is not getting called. What is the issue with this code. Is m missing any thing in implementation?

$http calls are always async. Meaning, even you do a .then at your service, there is no way it will properly the resolved data back into your controller. You will have to write it in your controller.
Your Service:
module.service('BrandService', function($http) {
var brands = [];
this.getBrands = function() {
//do not need the dot then.
return $http.get('http://admin.localhost/cgi-bin/brand.pl')
}
//simply returns the brands list
this.list = function() {
return brands;
}
});
In your controller:
module.controller("brandsController", function($scope, BrandService) {
BrandService.list()
.then(function(response) {
$scope.brandlist = response.brands;
alert($scope.brandlist);
});
});

In service:
this.getBrands = function() {
$http.get('http://admin.localhost/cgi-bin/brand.pl').then(function(response) {
brands = response.brands;
alert(brands);
return brands;
});
}
In controller:
$scope.brandlist = BrandService.getBrands();
alert($scope.brandlist);

Related

Angular & Firebase list not updating

i'm new with both Angular & Firebase. I've been trying to create a factory to update my list of stations but the list just won't seem to update.
When i run the factory code firebase.database... in my controller it works fine though.
controller
.controller('DashCtrl', function ($scope,Stations) {
$scope.stations = [];
$scope.stations = Stations.getStations();
})
services
.factory('Stations', function() {
return {
getStations : function(){
firebase.database().ref('stations').once('value',function(snapshot){
console.log(snapshot.val());
return snapshot.val();
})
}
}
})
What am i doing wrong? Isn't the ng-repeat="(key,station) in stations" list supposed to change after the factory returns the new data ?
Also I've been noticing something in a few tutorials. What is the difference between the below 2 inits.
.controller('DashCtrl', function ($scope,Stations) {
$scope.stations = [];
$scope.stations = Stations.getStations();
})
.controller('DashCtrl', [$scope,Stations,function ($scope,Stations) {
$scope.stations = [];
$scope.stations = Stations.getStations();
}])
since you didn't wrap the firebase result with an Angular promise, the angular environment cannot notice there are new results arrived, you have two solutions:
using Angular Fire which provide angular bindings for firebase
wrap the return result with an $q promise:
//controller
.controller('DashCtrl', function ($scope,Stations) {
$scope.stations = [];
Stations.getStations().then(function(results){
$scope.stations = results;
});
})
//service
.factory('Stations', function($q) {
return {
getStations : function(){
var defer = $q.defer();
firebase.database().ref('stations').once('value').then(function(snapshot){
defer.resolve(snapshot.val());
}).catch(function(error){
defer.reject(error);
})
return defer.promise;
}
}
})
controller #1
.controller('DashCtrl', function ($scope,Stations) {
$scope.stations = [];
$scope.stations = Stations.getStations();
})
controller #2
.controller('DashCtrl', [$scope,Stations,function ($scope,Stations) {
$scope.stations = [];
$scope.stations = Stations.getStations();
}])
controller #2 is better for minification done by browsers which will result something like:
controller2.min.js
.controller('DashCtrl', [a,b, function(a,b) {
a.stations = [];
a.stations = b.getStations();
}])

pass data between controllers in AngularJS dynamically [duplicate]

This question already has answers here:
Share data between AngularJS controllers
(11 answers)
Closed 2 years ago.
i have tow controller in angularjs. if one controller change data other controller display updated data. in fact first controller has a event that it occur second controller display it. for this propose i wrote a service. this service has tow function. here is my service code.
app.service('sharedData', function ($http) {
var data=[]
return {
setData: function () {
$http.get('/getData').success(function(response){
data = response;
})
},
getData: function(){
return data;
}
}
});
in first controller
app.controller("FirstController", function ($scope, $http,sharedData)
{
$scope.handleGesture = function ($event)
{
sharedData.setData();
};
});
in second controller:
app.controller("SecondController", function ($scope,sharedData) {
var data=[];
data = sharedData.getData();
}
);
in first controller setData work with out any problem but in second controller not work correctly. how to share data dynamically between tow controllers?
You are on the right track with trying to share data between controllers but you are missing some key points. The problem is that SecondController gets loaded when the app runs so it calls sharedData.getData() even though the call to setData in the firstController does not happen yet. Therefore, you will always get an empty array when you call sharedData.getData().To solve this, you must use promises which tells you when the service has data available to you. Modify your service like below:
app.service('sharedData', function ($http, $q) {
var data=[];
var deferred = $q.defer();
return {
setData: function () {
$http.get('/getData').success(function(response){
data = response;
deferred.resolve(response);
})
},
init: function(){
return deferred.promise;
},
data: data
}
})
And the secondController like this:
app.controller("SecondController", function ($scope,sharedData) {
var data=[];
sharedData.init().then(function() {
data = sharedData.data;
});
});
For more info on promises, https://docs.angularjs.org/api/ng/service/$q
You had multiple syntax problems, like service name is SharedData and you using it as SharedDataRange, the service is getting returned before the get function.
What I have done is corrected all the syntax errors and compiled into a plunkr for you to have a look. Just look at the console and I am getting the data array which was set earlier in the setter.
Javascript:
var app = angular.module('plunker', []);
app.controller("FirstController", function ($scope,sharedDateRange)
{
sharedDateRange.setData();
});
app.controller("SecondController", function ($scope,sharedDateRange) {
var data=[];
data = sharedDateRange.getData();
console.log(data);
});
app.service('sharedDateRange', function ($http) {
var data=[];
return {
setData: function () {
data = ['1','2','3'];
}
,
getData: function(){
return data;
}
}
});
Working Example
If you want to keep sharedDataRange as the variable name and service name as sharedData have a look at this example
javascript:
var app = angular.module('plunker', []);
app.controller("FirstController", ['$scope','sharedData', function ($scope,sharedDateRange)
{
sharedDateRange.setData();
}]);
app.controller("SecondController", ['$scope','sharedData', function ($scope,sharedDateRange) {
var data=[];
data = sharedDateRange.getData();
console.log(data);
}]);
app.service('sharedData', function ($http) {
var data=[];
return {
setData: function () {
data = ['1','2','3'];
}
,
getData: function(){
return data;
}
}
});
You can bind the data object on the service to your second controller.
app.service('sharedData', function ($http) {
var ret = {
data: [],
setData: function () {
$http.get('/getData').success(function(response){
data = response;
});
}
};
return ret;
});
app.controller("FirstController", function ($scope, sharedData) {
$scope.handleGesture = function () {
sharedData.setData();
};
});
app.controller("SecondController", function ($scope, sharedData) {
$scope.data = sharedData.data;
});
What you need is a singleton. The service sharedData needs to be a single instance preferably a static object having a static data member. That way you can share the data between different controllers. Here is the modified version
var app = angular.module('app', []);
app.factory('sharedData', function ($http) {
var sharedData = function()
{
this.data = [];
}
sharedData.setData = function()
{
//$http.get('/getData').success(function(response){
this.data = "dummy";
//})
}
sharedData.getData = function()
{
return this.data;
}
return sharedData;
})
.controller("FirstController", function ($scope, $http,sharedData)
{
sharedData.setData();
})
.controller("SecondController", function ($scope,sharedData) {
$scope.data=sharedData.getData();
});
I have removed the event for testing and removed the $http get for now. You can check out this link for a working demo:
http://jsfiddle.net/p8zzuju9/

Passing page number param for infinite-scroll to return more results from the backend

I'm using infinite-scroll and I want to request more data using $http. So next page / next 10 results etc.
This is my current working code (I put this in a factory as I read on another post somewhere that this was a good idea, I'm now thinking a service might be better but I'm not sure yet):
angular.module('hotels', [])
.factory('hotels', function($http) {
var hotels = {};
hotels.get = function(callback) {
$http.get('/php/hotels.php').success(function(data) {
callback(data);
});
};
return hotels;
});
angular.module('app', ['hotels', 'infinite-scroll'])
.controller('hotelsCtrl', function ($scope, hotels){
hotels.get(function (data) {
$scope.hotels = data.results;
})
});
How do I pass back a param page=3 and have the backend return more results?
I thought it might look something like this but its not working.:
angular.module('hotels', [])
.factory('hotels', function($http) {
var hotels = {};
hotels.get = function(callback) {
$http.get('/php/hotels.php?page='+$scope.page).success(function(data) {
callback(data);
});
};
return hotels;
});
angular.module('app', ['hotels', 'infinite-scroll'])
.controller('hotelsCtrl', function ($scope, hotels){
$scope.page = $scope.page + 1;
hotels.get({page: $scope.page}, function (data) {
$scope.hotels.push.apply($scope.hotels, data.results);
})
});
Any ideas?
This does the job:
angular.module('hotels', [])
.factory('hotels', function($http) {
var hotels = {};
hotels.get = function(params, callback) {
$http.get('/php/hotels.php', {params: {page: params.page}}).success(function(data) {
callback(data);
});
};
return hotels;
});
angular.module('app', ['hotels', 'infinite-scroll'])
.controller('hotelsCtrl', function ($scope, hotels){
$scope.page = 1;
$scope.addMoreItems = function() {
$scope.hotels=[];
hotels.get({page: $scope.page}, function (data) {
//$scope.hotels.push(data.results);
for (var i = 0; i < data.length; i++) {
$scope.hotels.push(data[i]);
}
$scope.page+=1;
})
}
});

Angularjs; use $http in service returns reference instead of actual data

I'm using the services directive in Angularjs not factory and I need to populate a json file to local variable;
/* Contains projects on the town */
leMaireServicess.service('cityService', function($http) {
// JSON regions and cities loader
this.cities = [];
// initCities
this.initCities = function() {
this.cities = $http.get('data/census/cities.js').success(function(data) {
return data;
});
return this.cities;
};
// Get city info
this.getCity = function() {
return this.cities;
};
});
And in my controller I have
// Saved game controller
leMaireControllers.controller('GameCoreCtrl', function($scope, cityService) {
/* Control the town project slides */
cityService.initCities();
$scope.city = cityService.getCity();
console.log($scope.city);
});
But instead of returning the actual data, it returns;
Object {then: function, catch: function, finally: function, success: function, error: function}
You can use a watch to make this work (see plunker)
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope,cityService) {
//$scope.cities = [];
$scope.service = cityService;
cityService.initCities();
$scope.$watch('service.getCity()', function(newVal) {
$scope.cities = newVal;
console.log(newVal)
});
});
app.service('cityService', function($http) {
var that = this;
this.cities = [];
this.initCities = function() {
$http.get('data.js').success(function(data) {
that.cities = data.cities;
});
};
this.getCity = function() {
return this.cities;
};
});
$http returns a promise which is what you're setting this.cities to.
This might help explain more,
https://stackoverflow.com/a/12513509/89702
In your controller you should be able to do something like this...
cityService.initCity().then(function(data) { $scope.city = data; }
You are working with promises which represent the result of an action that is performed asynchronously. Try it this way:
leMaireServicess.service('cityService', function($http) {
this.promise = {};
// initCities
this.initCities = function() {
this.promise = $http.get('data/census/cities.js');
};
// Get city info
this.getCity = function() {
return this.promise;
};
});
And in the controller you need to put your code in a callback:
// Saved game controller
leMaireControllers.controller('GameCoreCtrl', function($scope, cityService) {
/* Control the town project slides */
cityService.initCities();
cityService.getCity().then(function(result){
$scope.city = result.data;
console.log($scope.city);
});
});

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