I am following https://github.com/StarterSquad/startersquad.github.com/tree/master/examples/angularjs-requirejs-2 folder structure in my app
inside services i have added following code
define(['./module'], function(services) {
'use strict';
services.factory('CreditCard', ['$http', function($http) {
function CreditCardFactory() {
function parseMessage(message) {
if (message.response) {
return message.response;
}
}
function CreditCard(value) {
angular.copy(value || {}, this);
}
CreditCard.$get = function(id) {
var value = this instanceof CreditCard ? this : new CreditCard();
$http({
method: 'GET',
url: '/creditcards/' + id
}).then(function(response) {
var data = response.data;
if (data) {
angular.copy(parseMessage(data), value);
}
});
return value;
};
CreditCard.prototype.$get = function(id) {
CreditCard.$get.call(this, id);
};
return CreditCard;
}
return CreditCardFactory;
}]);
});
i have followed this question and added above code in factory
Angularjs - customizing $resource
in this question
app.controller('CreditCardCtrl', function($scope, CreditCard) {
$scope.creditCard = CreditCard().get(3);
});
CreditCard is added without adding dependency as we add defualt angular services like $scope and $http.
if i dont add dependency
controllers.controller('myListCtrl', ['Phone','Phone1','loginForm','$scope','$http','user_resources',function(Phone,Phone1,loginForm,$scope,$http,user_resources,CreditCard){
then it gives undefined and if i add it in my controller as dependency and then try to call get function then response is not returned
controllers.controller('myListCtrl', ['Phone','Phone1','loginForm','$scope','$http','CreditCard',function(Phone,Phone1,loginForm,userSrv,$scope,$http,user_resources,CreditCard){
'CreditCard' isn't declared as a dependency in this example, therefore it is not being injected and is undefined...
controllers.controller('myListCtrl', ['Phone','Phone1','loginForm','$scope','$http','user_resources',
function(Phone,Phone1,loginForm,$scope,$http,user_resources,CreditCard){
To fix this, add 'CreditCard'...
controllers.controller('myListCtrl', ['Phone','Phone1','loginForm','$scope','$http','user_resources','CreditCard',
function(Phone,Phone1,loginForm,$scope,$http,user_resources,CreditCard){
In the second example, some dependencies are missing, causing the others to be in the wrong order in comparison to the function arguments...
controllers.controller('myListCtrl', ['Phone','Phone1','loginForm','$scope','$http','CreditCard',
function(Phone,Phone1,loginForm,userSrv,$scope,$http,user_resources,CreditCard){
Add the missing dependencies in the right order...
controllers.controller('myListCtrl', ['Phone','Phone1','loginForm','userSrv','$scope','$http','user_resources','CreditCard',
function(Phone,Phone1,loginForm,userSrv,$scope,$http,user_resources,CreditCard){
Related
I have the below shown resolve property assigned to the "/users" route. The $rootScope.resource has several HATEOAS style linkrels in it; "users" being one of the rels... Ultimately, I'm trying to follow ($get) the "users" linkrel and assign the output (another level of HATEOAS rels) to the "usersResource" property, which I will then access through my controller:
.when("/users", {
templateUrl: "/static/views/users.html",
controller: "usersController",
controllerAs: "usersController",
resolve: {
usersResource: function ($rootScope) {
if ($rootScope.resource) {
$rootScope.resource.$request().$get("users",{
linksAttribute: "_links",
embeddedAttribute: "_embedded"
})
.then(function successCallback(data) {
return data;
}, function errorCallback(data) {
return {}
})
}
else
return {};
}
}
})
Now, when I'm trying to access the "usersResource" from my controller I get undefined. The controller has currently no logic. I'm merely trying to output the usersResource content into console for the time being...
(function () {
angular
.module("HateoasApp")
.controller("usersController", usersController);
usersController.$inject = ["usersResource"];
function usersController(usersResource) {
var vm = this;
// properties
vm.usersResource = usersResource;
// objects
// functions
console.log(usersResource);
}
})();
Any comments/suggestions will be greatly appreciated. Thanks!
You're not returning anything from your resolve function:
return $rootScope.resource.$request()...
^^^^^^
I'm pulling in an array from an API, like so:
// in Service....
return $http.get(
'http://api.com/team/16110?Authorization=565eaa22251f932b9f000001d50aaf0b55c7477c5ffcdbaf113ebbda'
)
.success(function(data) {
return data;
})
.error(function(err) {
return err;
});
This works fine, but only for the one array of data that the URL calls. I want to be able to call in other specific arrays by adapting one part of the URL - 16110.
I want to be able to use a property from a separate property elsewhere within this $http call. I tried this:
'http://api.com/team/' + $scope.thisId +'?Authorization=565eaa22251f932b9f000001d50aaf0b55c7477c5ffcdbaf113ebbda'
But this just broke the Service.
Is there a relatively simple solution to this? I feel like I'm really close, but can't crack it.
UPDATE - the following solution works...
1. SERVICE
app.factory('DataService', ['$http', function($http) {
return {
getTeamDetailsById: function(teamId) {
return $http.get('http://api.com/team/' + teamId + '?Authorization=xxxxxx'
)
}
}]);
2. CONTROLLER
app.controller('NationsController', [
'$scope',
'DataService',
NationsController]);
function NationsController($scope, DataService) {
self = this;
DataService.getTeamDetailsById($scope.whichTeam).then(
function(response) {
//success callback
$scope.teamDetails = response.data;
},
function(response) {
//an error has occurred
});
}
3. response.data
I am expecting to get back an object from this. The API URL is fine, I've tried it directly and it returns the data ok.
Pass the id from the scope into the service:
app.factory("DataService", ["$http", function($http) {
return {
getTeamDetailsById: function(teamId) {
return $http.get('path/to/api' + teamId + '?Auth=xxxx')
}
};
}]);
Call it from the controller:
DataService.getTeamDetailsById($scope.teamId).then(function(response) {
//success callback
$scope.teamDetails = response.data;
}, function(response) {
//an error has occurred
});
This:
'http://api.com/team/' + '$scope.thisId' +'?Authorization=565eaa22251f932b9f000001d50aaf0b55c7477c5ffcdbaf113ebbda'
is equal to http://api.com/team/$scope.thisId?Authorization=[...], which is not what you want. Remove the quotes around $scope.thisID, like this:
'http://api.com/team/' + $scope.thisId +'?Authorization=565eaa22251f932b9f000001d50aaf0b55c7477c5ffcdbaf113ebbda'
This will work assuming you've set $scope.thisId to whatever resource's ID you want to fetch.
i have a service as follows
angular.module('starter.service')
.factory('authService', function($http) {
var service = {};
service.GetByUsername = function() {
return $http.get('/js/user.json');
}
return service;
})
i just need to know two things,
1. why its is declaring a object named service ?
2.its a service for getting an object, what changes should i change to add another function to post a object(do it in the same code)? dont remove current functionality.
You are using the factory method to create a service, so you need to create an object and return it (Dependency Injection will make sure this object is only instantiated once so it is used as a singleton).
Whether this object you are creating is called "service" or any other way, it doesn't matter, it will work anyway.
As Shankar shown in his example, adding more methods to your service is as easy as adding more methods to the object you are declaring. To clarify the example, I'll add the argument you want to post, and let whoever is using the service to decide what to do with the returned promise (as you do in GET method):
angular.module('starter.service')
.factory('authService', function($http) {
var service = {};
service.GetByUsername = function() {
return $http.get('/js/user.json');
}
service.PostUser = function(user) {
return $http.post("/url/to/post/user", user);
}
return service;
})
You question is not clear, but you can simply add new function to you factory service,
angular.module('starter.service')
.factory('authService', function($http) {
var service = {};
service.GetByUsername = function() {
return $http.get('/js/user.json');
}
service.PostUser = function() {
var data = {}
$http.post("/js/user.json", data).success(function(data, status) {
})
}
return service;
})
I have a service that retrieves data using promise :
...
return {
getData : getData
}
function getData(aParam) {
$http.get('test.json').then(function (response) {
return response.data;
});
}
...
In my controller, where the service is injected, I can call my method like this :
...
var myData = MyService.getData('foobar');
...
The service is called but when I inspect the myData content, I have to access it like this :
myData.$$state.value.foobarArray
Question : Is it possible to avoid the $$state.value part ?
Regards.
I'd add this as just a comment if I had enough pointz, but try adding return before $http.get.
Your service exposes an async function so it either needs to return a promise..
function getData(aParam) {
return $http.get('test.json');
}
...and resolve the promise in the controller.
MyService.getData('foobar').then(function(data){
var myData = data;
});
Or use a callback function...
function getData(aParam, callback) {
$http.get('test.json').then(function (response) {
callback(response.data);
});
}
... passed in from the controller.
MyService.getData('foobar', function(data){
var myData = data;
});
I cant explain the 'weird hierachy' off the top of my head but this should get you headed in the right direction.
Say I need to include a GroupId parameter to every request the user makes, but I don't want to modify every service call to include that. Is it possible to make that GroupId appended automatically to all requests, whether it is POST or GET query string?
I have been looking into the interceptor request function, but can't figure out how to make the change
** Edit **
Current working sample below is a combo of Morgan Delaney and haimlit's suggestions (I think it is a combom anyway). The basic idea is that if the request is a POST, modify config.data. For GET, modify params. Seems to work so far.
Still not clear on how the provider system works in Angular, so I am not sure if it is entirely approriate to modify the data.params properties here.
.config(['$httpProvider', function ($httpProvider) {
$httpProvider.interceptors.push(['$rootScope', '$q', 'httpBuffer', function ($rootScope, $q, httpBuffer) {
return {
request: function (config) {
if (config.data === undefined) {
//Do nothing if data is not originally supplied from the calling method
}
else {
config.data.GroupId = 7;
}
if (config.method === 'GET') {
if (config.params === undefined) {
config.params = {};
}
config.params.GroupId = 7;
console.log(config.params);
}
return config;
}
};
} ]);
} ]);
If your example works, great. But it seems to lack semantics IMHO.
In my comments I mentioned creating a service but I've set up an example Plunker using a factory.
Plunker
Relevant code:
angular.module( 'myApp', [] )
.factory('myHttp', ['$http', function($http)
{
return function(method, url, args)
{
// This is where the magic happens: the default config
var data = angular.extend({
GroupId: 7
}, args );
// Return the $http promise as normal, as if we had just
// called get or post
return $http[ method ]( url, data );
};
}])
.controller( 'myCtrl', function( $scope, $http, myHttp )
{
// We'll loop through config when we hear back from $http
$scope.config = {};
// Just for highlighting
$scope.approved_keys = [ 'GroupId', 'newkey' ];
// Call our custom factory
myHttp( 'get', 'index.html', { newkey: 'arg' }).then(function( json )
{
$scope.config = json.config;
});
});