Error: $injector:undef Undefined Value in angularjs - angularjs

The response of ajax is like ["99636941","74167247"]. But the values are not accepted by angularjs. The response is ok. If I declare the same response as static, then it is working properly.
app.factory("States", function(){
var states;
$.ajax({
url:'php/usersList.php',
type:'post',
success:function(data,status)
{
states = data;
console.log(states);
},
error:function(xhr,desc,err)
{
console.log(xhr);
console.log("Details: "+ desc + "\n error:"+err);
}
});
return states;
});

Couple of things to note:
Do not use jQuery ajax $.ajax in angularjs service - use $http instead as it will handle digest cycle by itself. Read: https://docs.angularjs.org/api/ng/service/$http
As you are making an ajax call, return states will get executed even before your ajax success event - try looking into Promises in javascript/angular js.
You may refactor this method like:
app.factory("States", function($http){
var getStates function(){
return $http.post('php/usersList.php');//ideally this should be a GET method
};
return {
getStates: getStates
}
});
And in theplace where you call this method:
var states;
States.getStates().then(function(data){
states = data;
})

If we make it more simpler, You can do it the following way.
app.factory("States", function($http){
var factory={};
factory.getStates=function($http){
return $http({
method:'GET',
url:'your URL'
});
};
/*similarly write as many functions as you need and then simply return the factory var*/
return factory;
});

Related

How to make two https calls in single controller on page load Angular JS

I am new to Angular JS
I am trying to make two API calls on page load but I want to do one after another once I got the response I want to call another Asynchronous calls. my service looks as below
can you please suggest me what should be the best way to achieve this.
(function(){
"use strict";
var APIservice = function($http,$base64,UtilService,$rootScope){
UtilService.setHeaders($rootScope.globals.currentUser.authdata);
var DataProvider = function(method,url,data){
return $http({
method: method,
url: url,
data:data
}).then(function(response){
console.log(response);
return response.data;
});
};
return {
DataProvider:DataProvider
}
}
var module = angular.module('expframework');
module.factory("APIservice",APIservice);
}());
Thanks in Advance
Just use promise chaining:
APIservice.DataProvider('GET', firstUrl).then(function(data1) {
return APIservice.DataProvider('GET', secondUrl);
}).then(function(data2) {
// ...
});

I set the service data,but after $http done, I cannot get the service data

My service define like this:
module.factory('portfolio',function(){
var data;
var selectedPort;
return{
getData: function(){
return data;
},
setData:function(portfolios){
data = portfolios;
},
getSelectedPort:function(){
return selectedPort;
},
setSelectedPort:function(portfolioDetail){
selectedPort = portfolioDetail;
}
}
});
And in my controller the code as follows:
module.controller('portfoliosController', function($scope,$http, alertService,stockService, userDataService, portfolio){
var req = {
method: 'get',
url: 'www.facebook.com',
headers: {
'Authorization': userDataService.getToken()
}
};
$http(req).then(function(reponse){
$scope.portfoliosPriceList = reponse['data'];
portfolio.setData($scope.portfoliosPriceList);
console.log(portfolio.getData())//At here,I can get the portfolio's data
}, function(){
alertService.setMessge("System maintenance , please try again later");
alertService.alert();
});
console.log(portfolio.getData())//At here, I cannot get the portfolio's data
});
the error is
Error: undefined is not an object (evaluating 'message.substr')
Anybody can help me to solve this problem?Actually, I really do not understand, why I cannot get the data outside the $http
The request that you do with the $http service is done asynchronously, so the callback that you pass to the .send is not immediately invoked.
The code that follows (the console.log) is executed just after the $http(req) call is made but before the callback is called when the request is responded.
Maybe you will understand better with an simpler example:
function portfoliosController() {
var data = 'Initial Data. ',
content = document.getElementById('content');
// setTimeout would be your $http.send(req)
// calledLater would be your .then(function() { ... })
setTimeout(function calledLater() {
data = 'Data coming from the server takes some time to arrive...';
content.innerHTML = content.innerHTML + data;
}, 1000);
content.innerHTML = content.innerHTML + data;
}
portfoliosController();
<div id="content">
This is because javascript is asynchronous, so the code:
portfolio.getData()
Is maybe executing before the data is returned from the service.
In this case, you should only use the data of the portfolio just after the request is complete (inside the .then() function of $http) or put a promise.
Here is the documentation for angular promises:
https://docs.angularjs.org/api/ng/service/$q

how to make synchronous http request in angular js

How to make blocking http request in AngularJS so that i can use the $http response on very next line?
In the following example, $http object doesn't return the result to the next line so that I can pass this result to fullcalender(), a JavaScript library, because $scope.data returns blank value.
This is the sample code:
$http.get('URL').success(function(data){
$scope.data = data;
});
$.fullCalender({
data: $scope.data
});
You can use promises for that.
here is an example:
$scope.myXhr = function(){
var deferred = $q.defer();
$http({
url: 'ajax.php',
method: 'POST',
data:postData,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
//if request is successful
.success(function(data,status,headers,config){
//resolve the promise
deferred.resolve('request successful');
})
//if request is not successful
.error(function(data,status,headers,config){
//reject the promise
deferred.reject('ERROR');
});
//return the promise
return deferred.promise;
}
$scope.callXhrAsynchronous = function(){
var myPromise = $scope.myXhr();
// wait until the promise return resolve or eject
//"then" has 2 functions (resolveFunction, rejectFunction)
myPromise.then(function(resolve){
alert(resolve);
}, function(reject){
alert(reject)
});
}
You can't, you'll need deal with it through promises, but you could try do it like this:
$http.get('URL').success(function(data){
angular.copy(data, $scope.data);
});
$.fullCalender({
data: $scope.data
});
but most people would just do
$http.get('URL').success(function(data){
$.fullCalender({
data: data
});
});
If whatever your fullCalender object is doesn't work with async data, you might need to wrap it in something like ng-if or force it to redraw when the data has been supplied. You can also force the controller to not load until the data is loaded by using the route resolve.
Here is a practical answer, courtesy of user Kirill Slatin who posted the answer as a comment. Practical use example at the bottom of the answer.
If, like me, you need to use that response object as a scope variable, this should work:
$http.get('URL').success(function(data){
$scope.data = data;
$.fullCalender = $scope.data;
$scope.$apply()
});
$scope.$apply() is what will persist the response object so you can use that data.
-
Why would you need to do this?
I'd been trying to create an "edit" page for my recipes app.
I needed to populate my form with the selected recipe's data.
After making my GET request, and passing the response data to the $scope.form, I got nothing... $scope.$apply() and Kirill Slatin helped big time. Cheers mate!
Here's the example from my editRecipeController:
$http.get('api/recipe/' + currentRecipeId).then(
function (data) {
$scope.recipe = data.data;
$scope.form = $scope.recipe;
$scope.$apply()
}
);
Hope that helps!

Getting a single result with angularjs factory in MEAN stack

I'm trying to grab a single result from my expressjs api from within my AngularJS factory.
The factory looks like this and grabs all posts from my api(written in expressjs and getting data from mongodb), which is working fine:
angular.module('bonsaiService', ['ngResource']).
factory('bonsaiService', function($q,$resource) {
var bonsaiResource = $resource('http://localhost:8888/api/bonsais/:bonsaiId',{},{
get:{
method: 'GET',
params:{bonsaiId:''},
isArray: true
}
});
return {
get:function(){
var q = $q.defer();
bonsaiResource.get({
},
function(resp){
q.resolve(resp);
},function(httpResponse){
q.reject(httpResponse);
});
return q.promise;
}
//find by id
};
});
What i've tried so far is adding :bonsaiId after the $resource url and adding params for that id like this: params:{bonsaiId: ''}.
The server part (expressJS) look like this:
router.route('/bonsais/:bonsaiId')
.get(function(req,res){
Bonsai.findOne(req.params.bonsaiId,function(err,bonsai){
if(err)
res.send(err);
res.json(bonsai)
})
})
When I call a local url (with and existing _id from mongodb) it works fine and returns my data in json :
http://localhost:8888/api/bonsais/536be2e2ae54668818000001
Now in the controller im trying to get this data in my scope, which is not working.
bonsaiService.get({bonsaiId:$routeParams.bonsaiId}).then(
function(data){
$scope.trees = data;
console.log(data);
});
How do I make this work?
You could use a more simple approach here.
The query method for $resource already defines a GET on an array, which is QUERY.
Why not write your service this way :
.factory('bonsaiService', ['$resource',
function($resource) {
return $resource('http://localhost:8888/api/bonsais/:bonsaiId', {
bonsaiId: '#bonsaiId'
});
}
])
And in your controller, it would work like this :
bonsaiService.query({
bonsaiId: $routeParams.bonsaiId
}, function success() {
//Your code
}, function err() {
//Your code
});
Don't forget to inject the service in the controller or the app file, if it's not done already.

angular js getting data from laravel and print it

Hi I'am trying a simple example of using a controller and a factory to get some data back to the view but for some reason I can't print it.
I managed to get the ajax call to work.
If I type the
$scope.sampleStyles = [{ sample: 'text here', text : 'dasdas'}
and don't use the ajax call it works
UPDATE: if I add an alert before assigning to my scope it works (ajax has time to do his thing)
anyone know how to overcome that?
CODE:
var packageApp = angular.module("packageApp", []);
packageApp.controller("MyController", function($scope, myFactory){
$scope.sampleStyles = [];
function init(){
$scope.sampleStyles = myFactory.getSampleStyles();
}
init();
});
packageApp.factory('myFactory', function($http, $log){
var factory = {};
var sampleStyles = [];
var tempData = {};
factory.update = function(){
$.ajax({
type: 'POST',
url: '/account/fetch-sample-styles',
data: {
source: 'ajax'
},
success: function(data, textStatus, XMLHttpRequest){
tempData = data;
}
});
alert(tempData);
sampleStyles = tempData;
}
factory.getSampleStyles = function(){
factory.update();
return sampleStyles;
};
return factory;
});
Are you using the AngularJs $http service? If so it will return a promise which you then operate on. Here is more on promises from the AngularJs docs.
My guess is, you are using an ajax.get(...) with a success callback defined inside. The problem is probably due to the success callback not belonging to the "AngularJs world."
To fix this, you need to tell AngularJs that its scope has changed. Use the $[Root]scope.$apply() function, and have the scope injected into your service as a dependency.
Something like this inside the factory:
$.ajax({
url: "/api/some/end/:point",
...
success: function(data) {
$scope.$apply(function() {
$scope.sampleStyles = data; // etc
});
}
});
I strongly recommend that you look into the $http service, it makes the above code much nicer, and is designed to play nice with the $scope.
$http.get("/api/end/point").then(function(response) {
// response.data points at the page data sent back, assuming that your
// api endpoint sends back JSON of the likes of
// { status: "SUCCESS", styles: [...] }
$scope.sampleStyles = response.data.styles;
});
EDIT:
Now that you posted some code, it seems like the root of your issue is based on the fact that the ajax get is an async call. Why are you even messing with using a temporary variable? Why not the following?
factory.update = function(){
$.ajax({
type: 'POST',
url: '/account/fetch-sample-styles',
data: {
source: 'ajax'
},
success: function(data, textStatus, XMLHttpRequest){
sampleStyles = data;
}
});
}
If you really wanted to make the $.ajax call blocking, you can set async: false in the $.ajax properties.
EDIT 2:
Fixed some broken links, sorry I am a SO newb :(

Resources