Angular controller service promise not working - javascript

I want to wait for an http response before exiting angular controller. I have written the following code. But id doesn't work as the controller still exits before the http call is returned. Can anyone help me out to fix this? Thanks in advance.
var app = angular.module('app', []);
app.factory('MyService', function ($http) {
return $http.get('/api/endpoint').then(function(res){
return res.data;
});
});
app.controller('MyController', ['$scope', '$http', 'MyService', function($scope, $http, MyService){
MyService.then(function(data){
$scope.myVarialbe = data;
})
}]);

I would write this as below.
'use strict';
(function () {
function MyService($http) {
function getService() {
var url = yourURL;
return $http({ method: 'GET', cache: false, url: url });
}
return {
getService: getService
};
}
angular.module('app')
.factory('MyService', MyService);
}());
controller code:
MyService.getService().then(function(response) {
});

You can use like this factory just return request response promise and in controller use .then on returned promise.
var app = angular.module('app', []);
app.factory('MyService', ['$http',function($http) {
return {
getData: function() {
return $http.get('/api/endpoint');
}
};
}]);
app.controller('MyController', ['$scope', '$http', 'MyService', function($scope, $http, MyService){
MyService.getData().then(function(response){
$scope.myVarialbe = response.data;
});
}]);

Use $q is better.
Eg:
app.factory('MyService', ['$http', '$q', function($http, $q) {
return {
getData: function() {
var deferred = $q.defer();
$http.get('/api/endpoint')
.then( function(resp) {
deferred.resolve( resp.data );
});
return deferred.promise;
}
};
}]);
app.controller('MyController', ['$scope', 'MyService',function($scope, MyService){
MyService.getData().then(function(data){
$scope.myVarialbe = data;
})
}]);

Related

Multiple $http.get operatios and save the information in one $scope variable

I need to do four $http.get call and I need to send returned $scope variable to the one HTML to print all the information. In the moment I have the next code in JS:
(function (ng) {
var mod = ng.module("serviciosAdminModule");
mod.controller('serviciosAdminCtrl', ['$scope', '$http',
function ($scope, $http) {
$http.get("api/hoteles").then(function (response) {
$scope.serviciosHotelesRecords = response.data;
});
}]);
mod.controller('serviciosAdminCtrl', ['$scope', '$http',
function ($scope, $http) {
$http.get("api/paseos").then(function (response) {
$scope.serviciosPaseosRecords = response.data;
});
}]);
mod.controller('serviciosAdminCtrl', ['$scope', '$http',
function ($scope, $http) {
$http.get("api/aseos").then(function (response) {
$scope.serviciosAseosRecords = response.data;
});
}]);
mod.controller('serviciosAdminCtrl', ['$scope', '$http',
function ($scope, $http) {
$http.get("api/entrenamientos").then(function (response) {
$scope.serviciosEntrenamientosRecords = response.data;
});
}]);
})(window.angular);
In the HTML I have the next:
<tr ng-repeat="servicio in serviciosAdminRecords">
<td id="{{$index}}-id" class="parrafoscards" style="font-size: 16px">
<a ui-sref="servicioAdminDetail({servicioId: servicio.id})">{{servicio.id}}</a>
</td>...
In the HTML I ask for serviciosAdminRecords that is the $scope variable where I want to put all the .get data
You probably need to chain the promises in order to add all the responses together into the one array. Get rid of all the different controllers - they will have separate scopes - and just have the one controller, making sure it is being used in the view by using ng-controller='serviciosAdminCtrl' as an attribute in your view.
mod.controller('serviciosAdminCtrl', ['$scope', '$http',
function ($scope, $http) {
$scope.serviciosAseosRecords = [];
$http.get("api/hoteles").then(function (response) {
$scope.serviciosAseosRecords = $scope.serviciosAseosRecords.concat(response.data);
$http.get("api/paseos").then(function (response) {
$scope.serviciosAseosRecords = $scope.serviciosAseosRecords.concat(response.data);
$http.get("api/aseos").then(function (response) {
$scope.serviciosAseosRecords = $scope.serviciosAseosRecords.concat(response.data);
$http.get("api/entrenamientos").then(function (response) {
$scope.serviciosAseosRecords = $scope.serviciosAseosRecords.concat(response.data);
});
});
});
});
}]);
If your response.data is an array of object then initialize serviciosPaseosRecords as array.
$scope.serviciosHotelesRecords = [];
instead of assigning response.data to serviciosPaseosRecords
$scope.serviciosAseosRecords = response.data
Concat response.data with existing serviciosAseosRecords array.
$scope.serviciosAseosRecords = $scope.serviciosAseosRecords.concat(response.data)

Service returning undefined to the controller

This is my service:
'use strict';
app
.service('myService', function($http) {
this.getJSON = function() {
return $http.get('someUrl/dataForm').then(function(data){
return data.result;
});
};
});
And in my controller I have:
'use strict'
app.controller('myController', function ($scope, myService) {
myService.getJSON().then(function(data){
$scope.myData =data;
});
console.log($scope.myData);
});
I can see that the http call is successfully returning a JSON value but the console log shows that the value of myData is undefined.
What am I doing wrong ?
Place the console.log inside
myService.getJSON().then(function(data){
$scope.myData =data;
console.log($scope.myData);
});
DEMO
Change the code of your controller:
'use strict'
app.controller('myController', function ($scope, myService) {
myService.getJSON().then(function(data){
$scope.myData =data;
console.log($scope.myData);
});
});
This happen because getJSON is an asycronous method, the request to getJSON method not provoke that javascript wait to response, adding console.log in ".then" will solve your issue.
By the way, with getJSON you are working with a concept named "promises", i let you a link explanatory about that with $http
https://docs.angularjs.org/api/ng/service/$http
Update the code in the controller
'use strict';
app.service('myService', function($http) {
this.getJSON = function() {
return $http.get('someUrl/dataForm').then(function(data){
return data.result;
});
};
});
controller
'use strict'
app.controller('myController', function ($scope, myService) {
myService.getJSON().then(function(data){
$scope.myData =data;
console.log($scope.myData);
});
});
$http.get() returns promise object.
promise object has then(), catch(), finally() methods.
then is called when success, catch when error.
change your service to,
app.service('myService', function($http) {
this.getJSON = function() {
return $http.get('someUrl/dataForm'); //returns promise object
};
});
and controller to,
app.controller('myController', function($scope, myService) {
var promise = myService.getJSON();
//after resolving then method get called
promise.then(function(data) {
$scope.myData = data;
console.log($scope.myData);
});
});

TypeError: Cannot read property 'addTopic' of undefined. Am I blind?

since I've been staring at this problem for some days now, I'm kinda new at AngularJS, I thought maybe someone here could help me. So to my problem:
I get a Typeerror when i try to save a new topic on a forum I'm creating: My controller
module.controller('newTopicController', ['$scope', '$http', 'dataService', function ($scope, $http, $window, dataService) {
$scope.newTopic = {};
$scope.save = function () {
dataService.addTopic($scope.newTopic)
.then(function () {
$window.location = "/#";
},
function () {
alert("couldnt save topic");
});
};
}]);
And my factory:
module.factory("dataService", function ($http, $q) {
var _topics = [];
var _isInit = false;
var _isReady = function () {
return _isInit;
};
var _getTopics = function () {
var deferred = $q.defer();
$http.get("/api/topics?withReplies=true")
.then(function (result) {
angular.copy(result.data, _topics);
_isInit = true;
deferred.resolve();
},
function () {
deferred.reject();
});
return deferred.promise;
};
var _addTopic = function (newTopic) {
var deferred = $q.defer();
$http.post("/api/topics", newTopic)
.then(function (result) {
var createdTopic = result.data;
_topics.splice(0, 0, createdTopic);
deferred.resolve(createdTopic);
},
function () {
deferred.reject();
});
return deferred.promise;
};
return {
topics: _topics,
getTopics: _getTopics,
addTopic: _addTopic,
isReady: _isReady
};
});
So when i try to add a topic to the forum I just get "TypeError: Cannot read property 'addTopic' of undefined" in the controller, right where dataService.addTopic($scope.newTopic) is.
I also have another controller who also uses the factory, but that shouldnt be a problem right?
Thanks for your time.
This seems incorrect:
module.controller('newTopicController', ['$scope', '$http', 'dataService', function ($scope, $http, $window, dataService) {...}
Change it to:
module.controller('newTopicController', ['$scope', '$http', '$window', 'dataService', function ($scope, $http, $window, dataService) {...}

Pass value to factory angularjs

I would like to pass article id from url to factory but I can't get the value from $routeChangeSuccess callback.
myApp.controller('editCtrl', function($rootScope, $scope, getArticleById, $filter, $route, $routeParams) {
var article_id = $rootScope.$on('$routeChangeSuccess', function () {
return $routeParams.id;
});
getArticleById.get(article_id).then(function(data) {
$scope.articles = data;
});
});
myApp.factory('getArticleById', function($q, $http) {
return {
get: function(article_id) {
var deferred = $q.defer();
$http.get('/api/admin/article/edit/'+ article_id).success(function(result) {
deferred.resolve(result);
}).error(function(result) {
deferred.reject(result);
});
return deferred.promise;
}
}
});
$routeProvider
var myApp = angular.module('myApp',['ngRoute','ui.utils','ngSanitize','ui.tinymce'])
.config(function ($routeProvider, $locationProvider) {
//configure the routing rules here
$routeProvider.when('/admin/article/edit/:id', {
controller: 'editCtrl'
});
//routing DOESN'T work without html5Mode
$locationProvider.html5Mode(true);
}
);
Instead of creating a var named article_id in your controller, simply use the $routeParams.id to pass the value to factory.
getArticleById.get($routeParams.id).then(function(data) {
$scope.articles = data;
});
You can just update the articles in the $routeChangeSuccess callback.
myApp.controller('editCtrl', function($rootScope, $scope, getArticleById, $filter, $route, $routeParams) {
$rootScope.$on('$routeChangeSuccess', function () {
getArticleById.get($routeParams.id).then(function(data) {
$scope.articles = data;
});
});
});
This might cause problems when there is multiple route changes in quick successions. In which case you would need to do some more work.

Return true or false from laravel to Angularjs $scope

I'm trying to return true or false from Laravel to a $scope directive in Angularjs. This is the laravel code that is called:
public function check() {
return Response::json(Auth::check());
}
This is the service that queries Laravel:
app.factory('UserService', ['$http', '$location', function($http, $location) {
return {
loggedIn: function() {
var c = $http.get('/auth/check');
c.success(function(data) {
console.log(data);
return data;
});
}
}
}]);
The response logs fine in the console, but I cant seem to bind it to a $scope directive:
app.controller('BaseController', ['$scope', 'UserService', function($scope, UserService) {
$scope.loggedIn = UserService.loggedIn();
}]);
Returns nothing when I call it as:
{{ loggedIn }}
...in my view.
Any help?
The $http service returns a promise. So you would have to write something like
app.factory('UserService', ['$http', '$location', function($http, $location) {
return {
loggedIn: function() {
return $http.get('/auth/check');
}
}
}]);
Controller:
UserService.loggedIn().success(function(data) {
$scope.loggedIn = data;
});

Categories

Resources