/TypeError: Cannot read property 'getToken' of undefined/
I am trying to call getToken function which is defined in the factory function.
Both directive and factories are in separate .js file
but it is throwing an error and is not able to access the function.
angular.module('pesaveWeb')
.directive('goals', function goalsDrctv ($timeout) {
'use strict';
return {
restrict: 'E',
replace: true,
scope: true,
templateUrl: "js/directives/goals.tmpl.html",
controllerAs: 'savings',
controller: function ($routeParams, $scope,
savingsFactory,tokenFactory) {
this.message = {};
var token=tokenFactory.getToken();
var getGoals = savingsFactory.getGoals(token);
if (getGoals) {
getGoals.then( angular.bind(this, function (response) {
savingsFactory.message = response;
this.message = savingsFactory.message;
alert(JSON.stringify(this.message));
}) );
}
}
}
});
angular.module('pesaveWeb').factory('tokenFactory', function tokenFactory ($http,$routeParams) {
'use strict';
var obj = {};
obj.getToken = function () {
return $http({
method: 'POST',
url: "../api/v1/getToken",
headers : {
'Content-Type':'application/json',
'X-API-KEY':'04g4g00c04ks4sokgkoosg0kwww0cww4www0kc80',
'Authorization':"Basic cGVzYXZlQXBwOkNDNTVzV0FwUW0zYWxpazlLNTcwTTFXQ1RNOUJ1TmZS"
},
data: {"grant_type":"client_credentials"}
}) .success(function (data) {
})
.error(function (data) {
});
};
});
Your factory function needs to return the obj you are using to bind the function to.
angular.module('pesaveWeb').factory('tokenFactory', function tokenFactory ($http,$routeParams) {
'use strict';
var obj = {};
obj.getToken = function () {
return $http({
method: 'POST',
url: "../api/v1/getToken",
headers : {
'Content-Type':'application/json',
'X-API-KEY':'04g4g00c04ks4sokgkoosg0kwww0cww4www0kc80',
'Authorization':"Basic cGVzYXZlQXBwOkNDNTVzV0FwUW0zYWxpazlLNTcwTTFXQ1RNOUJ1TmZS"
},
data: {"grant_type":"client_credentials"}
}) .success(function (data) {
})
.error(function (data) {
});
};
return obj;
});
Also, another potential problem is the getToken() function might not work as expected. You should use a "promise" for resolving the value of token in your getToken() function using Angular's $q service. Check out its documentation here
Related
Component:
crudModule.js
var crudModule = angular.module('crudModule', ['ui.router', 'smart-table', 'ngCookies', 'ui.bootstrap', 'angularModalService', 'dialogs', 'remoteValidation']);
angular.module('crudModule').component('applicationInfo', {
templateUrl: 'infoApplication.html',
controller: 'applicationInfoCtrl'
});
applicationInfoCtrl.js:
var crudModule = angular.module('crudModule')
crudModule.controller('applicationInfoCtrl', ['httpService', '$scope', function($http, $scope, $cookies, $stateParams, httpService) {
httpService.httpGetRequest("http://localhost:8080/applications/" + $stateParams.id).then(function success(response) {
$scope.application = response.data;
});
$scope.getApiKey = function () {
httpService.httpGetRequest('http://localhost:8080/applications/generateApiKey').then(function success(response) {
$scope.application.apikey = response.data.apikey;
$scope.application.apisecret = response.data.apisecret
})
};
$scope.send = function (object, url) {
httpService.httpPostRequest(object, url + "/" + $stateParams.id).catch(function(error) {
console.log('There has been a problem with your fetch operation: ' + error.message);
}).then(function success(response){
});
}
}]);
httpService.js:
var crudModule = angular.module('crudModule')
crudModule.factory('httpService', function($http) {
return {
httpGetRequest: function (url) {
return $http({
method: 'GET',
url: url
})
},
httpPostRequest: function (object, url){
return $http({
method:'POST',
url: url,
data: object
})
}
}
});
I am getting error:
Cannot read property 'httpGetRequest' of undefined.
I have injected my httpService and i dont find any mistakes yet
The problem is the order of parameters in your controller, it should be
crudModule.controller('applicationInfoCtrl', ['$http','httpService', '$scope','$cookies','$stateParams' function(http,httpService, $scope,$cookies,$stateParams) {
}
I have this service :
(function() {
'use strict';
angular
.module('myApp')
.factory('Consultant', Consultant);
Consultant.$inject = ['$resource', 'DateUtils'];
function Consultant ($resource, DateUtils) {
var resourceUrl = 'api/consultants/:id';
return $resource(resourceUrl, {}, {
'query': { method: 'GET', isArray: true},
'get': {
method: 'GET',
transformResponse: function (data) {
data = angular.fromJson(data);
return data;
}
},
'update': {
method: 'PUT',
transformRequest: function (data) {
return angular.toJson(data);
},
transformResponse: function (data) {
data = angular.fromJson(data);
return data;
}
},
'save': {
method: 'POST',
transformRequest: function (data) {
return angular.toJson(data);
},
transformResponse: function (data) {
data = angular.fromJson(data);
return data;
}
}
});
}
})();
What if I want to add the url api/consultantscustom/:id (with its query/get/update methods) to this service?
As it seems that this file can contain only one factory, is there a way to do that or do I need to create another file with a new factory?
Maybe I am totally misunderstanding what you are asking, but you can have as many factories in one file as you like (or as seems useful):
(function() {
'use strict';
angular.module('myApp')
.factory('Consultant', Consultant)
.factory('Custom', Custom);
Consultant.$inject = ['$resource', 'DateUtils'];
Custom.$inject = ['$resource'];
function Consultant ($resource, DateUtils) {
var resourceUrl = 'api/consultants/:id';
...
}
function Custom ($resource) {
var resourceUrl = 'api/consultantscustom/:id';
...
}
Or, if you want to re-use the same factory to access different URLs, you could add methods to set the URL and then re-use the call to the generic resource.
function Consultant ($resource, DateUtils) {
function consultants () {
_call_resource('api/consultants/:id');
}
function custom () {
_call_resource('api/consultantscustom/:id');
}
function _call_resource (resourceUrl) {
return $resource(resourceUrl, {}, {
...
}
}
this.consultants = consultants;
this.custom = custom;
return this;
}
I have this code in my post.serv.js and in my controller I want to execute the function delete.
"use strict";
app.factory('JnttPost', function ($resource) {
var PostResource = $resource('/api/post/:_id', {
_id: "#id"
}, {
update: {
method: 'PUT',
isArray: false
}
}, {
delete: {
method: 'DELETE',
isArray: false
}
});
return PostResource;
});
I already know how to get and update a post, for example in my createpost.serv.js
"use stric";
app.factory('JnttCreatePost', function ($http, $q, JnttPost) {
return {
createPost: function (newPostData) {
var newPost = new JnttPost(newPostData);
var dfd = $q.defer();
newPost.$save().then(function () {
dfd.resolve();
}, function (response) {
dfd.reject(response.data.reason);
});
return dfd.promise;
}
};
});
and in my newpost.ctrl.js
"use strict";
app.controller('CtrlNewPost',
function ($scope, $location, JnttIdentity, JnttNotifier, JnttCreatePost) {
var email = ...;
$scope.newPost = function () {
var newPostData = {...};
JnttCreatePost.createPost(newPostData).then(function () {
JnttNotifier.notify('success', 'The post has been created');
$location.path('/');
}, function (reason) {
JnttNotifier.notify('error', reason);
});
};
});
I can't realize how to perform the delete request, I can do with a $http
In my new controller for do deletePost() function I have this:
$scope.deletePost = function () {
var pwd = JnttIdentity.currentUser.hashed_pwd;
var postidd = {
password: pwd,
id: $scope.post._id
};
var config = {
method: "DELETE",
url: '/api/post/',
data: postidd,
headers: {
"Content-Type": "application/json;charset=utf-8"
}
};
$http(config);
$location.path('/');
};
This actually already do this stuff but I want to do this without the $http like the create request, How I can do this? How do I can edit this code below for do the request?
createPost: function (newPostData) {
var newPost = new JnttPost(newPostData);
var dfd = $q.defer();
newPost.$save().then(function () {
dfd.resolve();
}, function (response) {
dfd.reject(response.data.reason);
});
return dfd.promise;
}
In my routes.js in express I have this route:
app.delete('/api/post/', posts.deletePost);
You can either call delete on the $resource class you create (JnttPost) or call $delete on a post that's returned from the $resource class.
The $resource class already has get/save/query/remove/delete functions included so you don't need to add the delete (save is create/POST, so you need to include update with PUT).
Here's a sample of using your $resource class to call delete:
angular.module('test', ['ngResource'])
.factory('JnttPost', function ($resource) {
var PostResource = $resource('/api/post/:_id', {
_id: "#id"
}, {
update: {
method: 'PUT',
isArray: false
}
});
return PostResource;
})
.run(function(JnttPost){
JnttPost.delete({id: 123123123});
});
I'm not quite sure what I'm doing wrong, but it seems that my profile doesn't resolve by the time we get to the MainCtrl. The user however does, resolve. Am I, perhaps not fetching the profile information properly in the Auth Service?
Router:
angular.module('app')
.config(function ($stateProvide) {
$stateProvider
.state('main', {
url: '/main',
templateUrl: 'app/main/main',
controller: 'MainCtrl',
resolve: {
user: function (Auth) {
return Auth.getUser();
},
profile: function (user) {
return Auth.getProfile();
}
}
});
});
Controller:
angular.module('app')
.controller('MainCtrl', function ($scope, user, profile) {
$scope.user = user;
$scope.profile = profile; <- DOESNT RESOLVE
});
Auth Service:
angular.module('app')
.factory('Auth', function ($firebaseSimpleLogin, $firebase, FBURL) {
var ref = new Firebase(FBURL);
var auth = $firebaseSimpleLogin(ref);
var Auth = {
user: {},
getUser: function () {
return auth.$getCurrentUser();
},
getProfile: function(uid) {
return $firebase(ref.child('users').child(uid)).$asObject();
}
};
return Auth;
});
Something like
auth.$getCurrentUser()
returns a promise so you need a
.then(function(user) {
event before your callback complete
In your case you may just resolve on the then, something like
Auth.getUser().then(function(user){ return user; });
Also $asObject() needs $loaded() for it's promise
var obj = $firebase(ref).$asObject();
obj.$loaded()
.then(function(data) {})
Try this structure for your promises:
var fetchSomething = function (action, params) {
var promise = $http({
method: 'POST',
url: 'someurl to the firebase',
data: params,
headers: {
'Access-Control-Allow-Origin': true,
'Content-Type': 'application/json'
}
}).success(function (data, status, headers, config) {
return data;
});
return promise;
};
I have some code in my controller that was directly calling $http to get data.
Now I would like to move this into a service. Here is what I have so far:
My service:
angular.module('adminApp', [])
.factory('TestAccount', function ($http) {
var TestAccount = {};
TestAccount.get = function (applicationId, callback) {
$http({
method: 'GET',
url: '/api/TestAccounts/GetSelect',
params: { applicationId: applicationId }
}).success(function (result) {
callback(result);
});
};
return TestAccount;
});
Inside the controller:
TestAccount.get(3, function (data) {
$scope.testAccounts = data;
})
How can I change this so rather than passing the result of success back it
passes back a promise that I can check to see if it succeeded or failed?
Make your service to return a promise and expose it to service clients. Change your service like so:
angular.module('adminApp', [])
.factory('TestAccount', function ($http) {
var TestAccount = {};
TestAccount.get = function (applicationId) {
return $http({
method: 'GET',
url: '/api/TestAccounts/GetSelect',
params: { applicationId: applicationId }
});
};
return TestAccount;
});
so in a controller you can do:
TestAccount.get(3).then(function(result) {
$scope.testAccounts = result.data;
}, function (result) {
//error callback here...
});