Reputation: 123
I am new to Angular, so if you ask the question: "Why don't you...?" The answer is...because I didn't know I could.
Have a factory make an API call, then inject that factory into a parent controller that will have scope over the entire page. Then have child controllers nested and inherit from the parent controller.
Here is what I have so far. I may be WAY off here, and if that is the case, please tell me. I am working on this alone, and have no help, so any help is welcomed.
Thank you.
var app = angular.module('myApp', []);
app.factory('myFactory', function($http){
var MyFactory = function(){};
MyFactory.getParams = function(){
return $http.get('/getparameters');
.success(function(data){
var roomname = data.roomname;
})
MyFactory.getRoom(roomname);
};
MyFactory.getRoom = function(room){
return $http.get('/my/api/' + room);
};
});
app.controller('RoomCtrl', function($scope, myFactory){
$scope.data = myFactory;
});
Upvotes: 1
Views: 73
Reputation: 1384
You don't need to use resource, you need use promise; EDITED I tried to make more clear for you
app.factory('apicall', ['$q','$http',function($q, $http){
function getRoom(options){
var promise = $http.get(options.paramUrl)
.success(function(data){
//handle your error
return $http.get(options.roomUrl + data.roomname);
})
.error(function(msg){
return $q.when(msg)
})
return promise;
}
return {getRoom:getRoom};
}])
if you want call your factory in where you want
app.controller('RoomCtrl', ['$scope','apicall',function($scope, apicall){
var options = {
paramUrl:'/getparameters',
roomUrl:'/my/api/'
}
apicall.getRoom.all(function(result){
$scope.data = result;
})
}]);
Upvotes: 0
Reputation: 1693
I usually separate different API calls in different factories that return a $resource
.
For example, let's say we have 2 different API calls that point to different resources:
yourwebsite.com/user/:userId - returns data about the user
yourwebsite.com/photo/:photoId - return data about some photo
In angular, you would split these in 2 different factories: "use strict";
angular.module("App.services").
factory("User",["$resource", function($resource){
return $resource("yourwebsite.com/user/:userId"),{userId:"@userId"});
}]);
and second
angular.module("App.services").
factory("Photo",["$resource", function($resource){
return $resource("yourwebsite.com/photo/:photoId"),{photoId:"@photoId"});
}]);
In your controller, you would use them like so:
angular.module("App.controllers").controller("TestController",["User","Photo", function(User, Photo){
User.get({
id:10
}).$promise.then(function(data){
console.log(data); //returns the data for user with the id=10
});
Photo.get({
id:123
}).$promise.then(function(data){
console.log(data);
});
}]);
Usually $resource
maps a CRUD API(what I posted above is a basic example of a GET call).Check out the documentation on $resource
- It already has the basic GET
, PUT
, POST
, DELETE
functions.
I would recommend using $http
if you have only 1 simple operation on that URL and not all 4 of them. You can then inject $http
in your controller and do the request there instead of creating a factory for it.
If you have 2 requests and they are chained(second one depends on the data received from the first one) you have to wait until the first one is resolved. With $resource
you can do this in the following way:
angular.module("App.controllers").controller("TestController",["User","Photo", function(User, Photo){
var user_promise = User.get({
id:10
}).$promise.then(function(data){
console.log(data); //returns the data for user with the id=10
return data;
});
var photo_promise = Photo.get({
id:123
}).$promise.then(function(data){
console.log(data);
return data;
});
user_promise.then(photo_promise).
catch(function(error){
console.log(error); //catch all errors from the whole promise chain
});
}]);
Upvotes: 0
Reputation: 326
The $q service helps you to handle combination of two asynchronous calls
app.factory('apicall', function($q, $http) {
var deferred = $q.defer();
$http.get('/getparameters')
.success(
function(data) {
var roomname = data.roomname;
$http.get(baseURL + 'room/' + roomname)
.success(
function(roomData) {
deferred.resolve(roomData);
}
)
.error(
function() {
deferred.reject();
}
)
})
.error(
function() {
deferred.reject();
}
);
return deferred.promise;
});
And here is controller where you can use your service
app.controller('someCtrl', function(apicall) {
apicall.then(
function(roomData) {
//success
},
function() {
//error
}
)
})
Upvotes: 0