Passing params to an angular service from a controller? - javascript

I'm an angular newby. I'm hoping to pass params to a service that fetches data form a server depending on those params.
for example, if I want to pass a book name string and then use it in the service to concatenate with the request url. The documentation does not show clearly in this subject and I could not find helpful examples in other resources.
Let say, this is the controller:
app.controller('BookController', ['$scope', '$routeParams', 'books', function($scope, $routeParams, books) {
// sending params to books service before a successful return
books.success(function(data) {
$scope.book = data[$routeParams.bookId];
});
and this is the service
app.factory('books', ['$http', function($http) {
// var url = 'http://...' + ParamFromController + '.json'
return $http.get(url)
.success(function(data) {
return data;
})
.error(function(err) {
return err;
});
}]);
So, how can I send params to 'books' service and then use it in the service?
Thanks a lot in advance.

You can declare your service as:
app.factory('books', ['$http', function($http) {
// var url = 'http://...' + ParamFromController + '.json'
return {
getVal: function(url,options){
return $http.get(url,options)
}
}
}]);
and use it in your controller and provide appropriate params to pass into 'books' service:
app.controller('BookController', ['$scope', '$routeParams', 'books', function($scope, $routeParams, books) {
// sending params to books service before a successful return
books.getVal('api/activity.json',{'name':'abc'}).success(function(data) {
$scope.book = data[$routeParams.bookId];
});
Also, dont use the .success() callback both in your service and controller function. The books service is returning a promise($http returns a promise implicitly) and you can handle that in controller.

Right now you are returning the promise / result of the $http as the service instance.
Services are not meant to work this way. You should return an object that holds several properties / methods that define your service:
app.factory('books', ['$http', function($http) {
var instance = {
getBook: function(bookId) {
return $http.get(...);
}
}
return instance;
}
In the controller you can then use the books service as follows:
books
.getBook($routeParams.bookId)
.then(function (result) { ... });

app.factory('books', ['$http', function($http) {
var booksService = {};
booksService.getBook = function(bookId){
{
return $http.get(url, bookId);
};
return booksService;
}]);
and in your controller
app.controller('BookController', ['$scope', '$routeParams', 'books', function($scope, $routeParams, books) {
books.getBook($routeParams.bookId).success(function(data) {
$scope.book = data;
});

Related

Call function from one controller in another in angularjs

I currently have 2 javascript controllers: selectAll and listAllDomains.
I'm trying to call the method getBeanName (defined in listAllDomains) in the controller selectAll under:
response = $http.post('/invoke/selectAll/', INSERT_CALL_HERE);
As a note, the object returned by the method getBeanName will be passed as an argument to the $http.post() method and handled by a Java controller.
app.controller('listAllDomains', ['$http', '$scope', '$rootScope', function ($http, $scope, $rootScope) {
$scope.showSpinner = true;
$scope.showBtn = false;
let dataObj;
$http.get('domains/').then(function (response) {
$scope.showSpinner = false;
$scope.domains = response.data;
});
$scope.showButton = function(eleStatus) {
let eleSize = Object.keys(eleStatus).length;
return !eleSize;
};
$scope.getBeanName = function (objectType, objectName) {
dataObj = {
type : objectType,
name : objectName,
methodName : "select",
methodParameters : ["true"]
};
localStorage.setItem("dataObj", dataObj);
console.log(dataObj);
$rootScope.$emit("invokeSelectAll", dataObj);
return dataObj;
}
}]);
app.controller('selectAll', ['$http', '$scope' , '$rootScope',
function ($http, $scope, $rootScope) {
var response;
$rootScope.$on("invokeSelectAll", function(){
$scope.invokeSelectAll();
});
$scope.invokeSelectAll = function(){
console.log(localStorage.getItem("dataObj"));
response = $http.post('/invoke/selectAll/', INSERT_CALL_HERE);
response.success(function(data, status, headers, config) {
$scope.responses = data ? data : "Select Operation not supported on this bean";
});
}
}]);
Any help would be much appreciated! Thank you!
You can either create a service and inject it in both controllers or just define your function in $rootScope and then use it in any controller.
Check this issue for reference: How to use $rootScope in AngularJS
first create a service/factory with required function. And inject into the controller.

Data in factory nested can't be readed by controller (ANGULAR JS)

Well, I begin...
I've already a factory that loads the data from JSON files succefully:
FIRST FACTORY:
statisticsModule.factory('globalFactory', ['$http', function($http){
return $http.get('../statistics/php/config_statistics.json')
.success(function(data){
return data;
})
.error(function(err){
return err;
});
}]);
I want:
Read a specific URL that contains this JSON
Inject factory inside another factory that read the data for the URL above.
This factory load the data and returns by console that I want:
SECOND FACTORY:
statisticsModule.factory('statusFactory', ['globalFactory', '$http', function(globalFactory, $http){
return globalFactory.success(function(data){
var deserialize = angular.fromJson(data.config.graph_conf_array.arrayReportBD);
var statusUrl = deserialize[0];
$http.get(statusUrl).success(function(data){
console.log(data);
}).error(function(err){
err;
});
});
}]);
But I want a third task:
Inject data in controller
This is my controller:
statisticsModule.controller('tableController', ['statusFactory', '$scope', '$http', function(statusFactory, $scope, $http){
statusFactory.success(function(){
});
}]);
If I want loads data from Second Factory in my controller, How I do?
Sorry for bad english, and thanks in advance.
First of all don't use .success as it doesn't help in promise chaining. .success doesn't create a new promise it returns the original promise.
First Factory
statisticsModule.factory('globalFactory', ['$http', function($http){
return $http.get('../statistics/php/config_statistics.json')
.then(function(response){
return response;
}, function (error) {
return error.
})
}]);
Second Factory
statisticsModule.factory('statusFactory', ['globalFactory', '$http', function(globalFactory, $http){
return globalFactory.then(function(data){
var deserialize = angular.fromJson(data.config.graph_conf_array.arrayReportBD);
var statusUrl = deserialize[0];
return $http.get(statusUrl);
}).then(function (data) {
return data;
});
}]);
Now in your Controller
statisticsModule.controller('tableController', ['statusFactory', '$scope', '$http', function(statusFactory, $scope, $http){
statusFactory.then(function(data){ // data is the data received after get call to statusUrl
// do something
});
}]);

AngularJS App: Load data from JSON once and use it in several controllers

I'm working on a mobile app using AngularJS as a framework, currently I have a structure similar to this:
app.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/', {
templateUrl : 'pages/home.html',
controller : 'homeCtrl'
})
.when('/one', {
templateUrl : 'pages/one.html',
controller : 'oneCtrl'
})
.when('/two', {
templateUrl : 'pages/two.html',
controller : 'twoCtrl'
});
}]);
app.controller('homeCtrl', ['$scope', function($scope) {
}]);
app.controller('oneCtrl', ['$scope', function($scope) {
}]);
app.controller('twoCtrl', ['$scope', function($scope) {
}]);
And then I'm displaying the content with an ng-view:
<div class="ng-view></div>
Things are working well but I need to load data from a JSON file to populate all the content of the app. What I want is to make and an AJAX call only once and then pass the data through all my different controllers. In my first attempt, I thought to create a Service with an $http.get() inside of it and include that in every controller, but it does not work because it makes a different ajax request everytime I inject and use the service. Since I'm new using angular I'm wondering what is the best way or the more "angular way" to achieve this without messing it up.
Edit: I'm adding the code of the service, which is just a simple $http.get request:
app.service('Data', ['$http', function($http) {
this.get = function() {
$http.get('data.json')
.success(function(result) {
return result;
})
}
});
Initialize the promise once, and return a reference to it:
No need to initialize another promise. $http returns one.
Just tack a .then() call on your promise to modify the result
angular.module('app', [])
.service('service', function($http){
this.promise = null;
function makeRequest() {
return $http.get('http://jsonplaceholder.typicode.com/posts/1')
.then(function(resp){
return resp.data;
});
}
this.getPromise = function(update){
if (update || !this.promise) {
this.promise = makeRequest();
}
return this.promise;
}
})
Codepen example
Edit: you may consider using $http cache instead. It can achieve the same results. From the docs:
If multiple identical requests are made using the same cache, which is not yet populated, one request will be made to the server and remaining requests will return the same response.
Try this to get JSON Data from a GET Link:
(function (app) {
'use strict';
app.factory('myService', MyService);
MyService.$inject = ['$q', '$http'];
function MyService($q, $http) {
var data;
var service = {
getData: getData
};
return service;
//////////////////////////////////////
function getData(refresh) {
if (refresh || !data) {
return $http.get('your_source').then(function(data){
this.data = data;
return data;
})
}
else {
var deferrer = $q.defer();
deferrer.resolve(data);
return deferrer.promise;
}
}
}
}(angular.module('app')));
Now you can add this dependency in your controller file and use:
myService.getData().then(function(data){
//use data here
}, function(err){
//Handle error here
});

Reference $scope variables from within $http request angular

I am very new to angularjs and am having a hard time trying to figure out this issue.
Basically, we are using a factory to request data for our application. When the factory returns a promise, we were hoping that the data inside the returned promise that was defined in our scope, would be able to be used, but it is only returning as text on the page.
For example: We have defined $scope.name in our controller:
app.controller('AccountController',function($scope,Account) {
$scope.name = 'Abby';
$scope.news = [];
Account.getSnapshot().success(function(data) {
$scope.news.push(data);
});
});
so the factory (getSnapshot) will return something like "Hello {{name}}" from an $http request as follows:
app.factory('Account',function($http) {
return {
getSnapshot : function() {
return $http.get('data.php');
}
}
});
Is it possible to allow the factory to access /use {{name}} from the $scope?
You will need to use internal Angular $interpolate service:
app.controller('AccountController', function($scope, $interpolate, Account) {
$scope.name = 'Abby';
$scope.news = [];
Account.getSnapshot().success(function(data) {
var text = $interpolate(data)($scope);
$scope.news.push(text);
});
});
Use $q and promises thanks to #dfsq's answer on my post similar to this. Works perfectly.
Here's a plunker.
// Factory method.
app.factory('Account', function($http, $q) {
var data;
return {
getSnapshot: function() {
return data ? $q.when(data) : $http.get('data.json').then(function(response) {
data = response.data;
return data;
})
}
}
});
// Controller method.
app.controller('AccountController', function($scope, Account) {
$scope.name = 'Abby';
$scope.news = [];
Account.getSnapshot().then(function(data) {
$scope.news = data;
});
});

AngularJS service only running the first time controller is used

I have the following controller that uses a service Customers to return customers. The problem is that its only executing the service the first time the controller is run. Looking at my server I see its only performing the get request the FIRST time the controller used(loading that view) if I change views and say add a customer and come back to the view that list customers its not updated because there was not another get request from the service.
.controller('searchCTRL', ['$scope', '$http', 'Customers', function($scope, $http, Customers) {
$scope.customers = Customers;
$scope.deleteCustomer = function(id) {
$http.delete('/api/customer/' + id)
.success(function(data) {
$scope.customers.data = data;
})
.error(function(data) {
console.log('Error: ' + data);
});
};
}])
and
.factory('Customers', function($http){
var Customers = {};
$http.get('/api/customer')
.success(function(data) {
Customers.data = data;
})
.error(function(data){
console.log('error: ' + data);
});
return Customers;
});
if I stay on the view and reload the page it gets the data like it should but any subsequent visits to the page no longer execute the get. Any help would be appreciated.
Angular .factory is a singleton so it will always only run once. Also, the $http call is async so you should be using promise in order to get the data to your controller. Try the following:
.factory('Customers', function($http, $q){
return function () {
var d = $q.defer();
$http.get('/api/customer')
.success(function(data) {
d.resolve(data);
})
.error(function(data){
console.log('error: ' + data);
d.reject(data);
});
return d.promise;
};
});
and in your controller:
.controller('searchCTRL', ['$scope', '$http', 'Customers', function($scope, $http, Customers) {
Customers().then(function (data) {
$scope.customers = data;
});
...
As $http returns a promise, you can further simply your .factory by doing:
.factory('Customers', function($http){
return function () {
return $http.get('/api/customer');
};
})
For more detail, see documentation for $http.

Categories

Resources