This question already has answers here:
AngularJs error Cannot read property 'then' of undefined
(4 answers)
Closed 5 years ago.
I'm new to angularjs, and I know there are a lot of questions regarding this error,
Unfortunately I couldn't find an answer that fits my problem in any of them.
I've got a factory that holds all the functions, and controllers that use them. in one controller I got a GET function that returns an array, most of my functions are written almost the same, as well as functions that's written exactly the same like this one, only with different variables names/url, but this error occurs only with this function:
Controller:
$scope.getAllFunction = function(){
appServicesProvider.getAll($scope.var1).then(function(res){
$scope.var2 = res;
})
};
Factory (appServicesProvider) :
function getAll(var1){
$http.get(restURL+var1).then(
function(response){
return [].concat(response.data.var2)
}
);
}
As I said, there are more functions that's written exactly the same, only this one won't work, which makes it harder for me to solve.
Appreciate any help given!
You have to return the promise
function getAll(var1){
return $http.get(restURL+var1).then(
function(response){
return [].concat(response.data.var2)
}
);
}
Or you can rewrite your factory to return an object containing your resolved promise using $q
app.factory('appServicesProvider', function() {
return {
getAll: function(var1) {
var defer = $q.defer();
$http.get(restURL + var1).then(function(response) {
defer.resolve([].concat(response.data.var2));
}).catch(function(response, status) {
defer.reject(response.data.message);
});
return defer.promise;;
}
}
});
Related
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 3 years ago.
I am trying to get the value of $rootScope.exists from the SomeService.getData() function.
When I see the rootScope (using console.log) outside the function, I can see the $rootScope.exists value but on printing it, it says its undefined.
How can I get the value?
else {
SomeService.getData().then(function (response) {
$rootScope.1a = response.data;
$rootScope.levels = response.data.levels;
$rootScope.exists = checkAvailability($rootScope.accessLevels, "DataDAta");
});
console.log("sadsad", $rootScope.exists);
if ($rootScope.exists) {
$location.path('/ABC');
}
else {
$location.path('/DEF');
}
}
Did you inject '$rootScope' into your modules array?
app.controller('LoginCtrl', function($rootScope) {
}
This question already has answers here:
AngularJs ReferenceError: $http is not defined
(3 answers)
Closed 4 years ago.
I keep getting the following error:
Cannot read property 'get' of undefined
at Object.getChannelIdFromYoutubeUsername
at Object.vm.creatorAccountCreationFormSubmit
Even though I am injecting $http into my service, and whenever I paste the url being passed into the $http.get command, I get an output in my browser window.
Here is my service:
angular.module('adsomaApp').service('YoutubeService', function($log) {
var url = 'https://www.googleapis.com/youtube/v3';
function getChannelIdFromYoutubeUsername(youtubeApi, youtubeUsername, $http) {
var queryUrl = url + "/channels/?key=" + youtubeApi + "&forUsername=" + youtubeUsername + "&part=id";
return ($http.get(queryUrl).then(handleSuccess, handleError));
}
function handleSuccess(response) {
return response.data;
}
function handleError(response) {
if (!angular.isObject(response.data) || !response.data.message) {
return ($q.reject('An unknown error occurred.'));
}
return ($q.reject(response.data.message));
}
var youtubeService = {
getChannelIdFromYoutubeUsername: getChannelIdFromYoutubeUsername
};
return youtubeService;
});
Here is my controller:
vm.channelId = {};
vm.creatorAccountCreationFormSubmit = function() {
YoutubeService.getChannelIdFromYoutubeUsername(ConstantsService.youtubeSettings().youtubeApiKey, vm.connectYoutubeFormData.youtubeUsername).then(function(succ) {
vm.channelId = succ;
$log.info(vm.channelId);
}, function error(err) {
$log.error('Error: ', err);
});
};
angular.module('adsomaApp').service('YoutubeService', function($log, $http) { }
you didn't inject in service layer so it is showing undefin
Two basic changes:
Inject $http into the Service
angular.module('adsomaApp').service('YoutubeService', function($http, $log) {
Remove $http from the arguments of this service method
function getChannelIdFromYoutubeUsername(youtubeApi, youtubeUsername) {
The issue is that, when this Service Method is being called from the Controller, the third argument is NOT sent by you. Which, basically means, $http will be null.
I have addressed this issue by injecting $http in the service and by excluding the third argument in the method signature.
These two changes should take care of the issue. I have not included rest of the code.
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 5 years ago.
I have a problem about the scope of variables in a Cordova program.
This is my code:
angular.module('starter.services', [])
.factory('myFactory', function ($http) {
var myVar = "HELLO";
alert(myVar); //HELLO -> Correct
$http.get("URL").then(
function (response) {
myVar = response.data;
alert(myVar) // Correct Answer
}, function (error) {
console.log("Get config.json error - " + JSON.stringify(error));
}
);
alert(serverName); //HELLO -> why?
I declared my variable outside the http block. Can you help me? thanks
For one, you have never defined serverName so that will alert undefined.
Your final Alert is also being called before your $http.get() has returned, so myVar hasn't been updated. I think you should read up on the $http service (https://docs.angularjs.org/api/ng/service/$http) and how promises work (http://andyshora.com/promises-angularjs-explained-as-cartoon.html).
I am trying to use one controller method to fill different lists in my view.
var loadPlayers = function (division) {
var year = new Date().getFullYear() - parseInt(division);
console.log(year);
return PlayersService.getPlayersByDate(year).then(function(response){
return response;
});
};
$scope.playersU20 = loadPlayers(20);
$scope.playersU18 = loadPlayers(18);
PlayersService
this.getPlayersByDate = function (year) {
var promise = $http.get('/playerByYear/' + year).then(function(response) {
return response.data;
});
return promise;
};
But this is not working. It just works when I remove the return statements and just do $scope.playersU20 = response;. But this does not allow me to re-use the function. I hope I made myself clear.
Thank you
The then function returns a promise, so you'll need to update the scope in the success function invoked on promise fulfilment:
loadPlayers(20).then(function(players) { $scope.playersU20 = players; });
loadPlayers(18).then(function(players) { $scope.playersU18 = players; });
I would refactor to remove loadPlayers - it seems redundant when you can just use your players service directly in the controller if you used years rather than years ago. If you also need years ago, then add it as an additional function on your players service. You'll also want to add error handling.
Change the loadPlayers() function as following. The one you did on the question is not a re-usable function in javascript. I provide you a link to learn know about how to properly declare function in JavaScript. It will give you a better understanding not only just know how to make functions in Javascript, and also talk about the scope of functions. JavaScript Function Tutorial
function loadPlayers (division) {
var year = new Date().getFullYear() - parseInt(division);
console.log(year);
return PlayersService.getPlayersByDate(year).then(function(response){
return response;
});
};
$scope.playersU20 = loadPlayers(20);
$scope.playersU18 = loadPlayers(18);
This question already has answers here:
Angular Best practice: promise in a Factory or in a Controller?
(3 answers)
Closed 7 years ago.
Pretty new to Angular, what I want to ask is which practice is considered better between
Sending promise to the controller
Controller
factory.method()
.success(function (data) {
// do stuff
})
.error(function (data) {
// throw error
});
Service
return {
method: function() {
return $http.get(url);
}
};
and
Sending data to the controller
Controller
myValue = factory.method();
Service
return $http.get(url).then(function(req){
return req.data;
});
Note that I might be completely off-road here and second method might even not work (haven't tested it yet), but just wanted to ask out of curiosity. If there are better or more effectives practices I would be really glad to hear about them, thank you all very much.
I usually use the first solution that I can confirm it works pretty well. Among other things, for example it allows you to :
control asynchronous flow from your controllers
thus chain services, paralellize and join them, show spinners and stuff
reuse the same services in other asynchronous contexts, such as routes resolution
handle promise rejection
Edit:
That said, in addition, you could do both, like Restangular does with "enhanced promises". Returning a thenable thing, with an $object or $return or whatever attached to it would allow you to :
Use the promise
myService.myMethod.then(
function(data) {//Success
//Manipulate data
$scope.whatever = data;
},
function(err) {
//Handle error
}
);
Or just the $return, that will be populated later, when promise resolves
$scope.whatever = myService.myMethod().$return;
//Notice that you just can't handle rejection
An example of service like that, using angular $q service :
var deferred = $q.defer();
//Create $return reference
deferred.promise.$return = [];
deferred.promise.then(function(data) {
//replace $return elements with data elements, keeping reference
angular.copy(data, deferred.promise.$return);
});
setTimeout(function() {
deferred.resolve([
'White',
'Pinkman'
]);
}, 1000);
return deferred.promise;
Haven't tested this code, but you get the idea