angular 1.5 access data in http.get without scope - javascript

I am using Angular 1.5.
I can't access my data, from the http.get, out the http.get.
Let me explain:
I have my component:
(function(){
'use strict';
class myComponent {
constructor(
$http,
$scope)
{
var self = this;
self.test="this is a test";
$http.get(MYAPI).then(function(response){
self.MYDATA = response.data;
console.log(self.MYDATA)
});
console.log(self.test)
console.log(self.MYDATA)
}
}
angular.module('myApp')
.component('myApp.test', {
templateUrl: 'myTemplate.html',
controller: myComponent,
controllerAs:'vm',
});
})();
The console.Log give me:
this is a test --> for the test
undefined --> out the http.get
Object {id: 1…} --> in the http.get
So I can't access to my data out the http.get and this is what I want.

$http.get is an asynchronous call meaning the program execution doesn't wait for the data to be fetched from server .
Thus by the time console.log(self.MYDATA) located outside of $http.get() is executed , the data has not been fetched from server that is why you get a undefined error.
To solve this problem or to handle asynchronous calls , you could do something like this :
var promise = $http.get(MYAPI);
then access data in the following manner with the help of callbacks :
promise.then(
function successCallBack(response)
{
self.MYDATA = response.data;
console.log(self.MYDATA)
}
).then(
function errorCallBack(response)
{
console.log(response);
}
);
Here is a nice article on callbacks that could help you !

Related

How to access sub objects of an object returned by AngularJS data service inside controller

I have an angularjs data factory that makes a server call and sets the returned data in the factory returned object like this
angular.module('app').factory('DataService', function() {
// Returning object
return {
data: {},
isLoaded: false,
getData:getdata
};
function getData() {
var self = this;
//Some Ajax Call returns an 'dataObject'
self.data = dataObject; //dataObject has a few subObjects and list
}
});
Now inside my angularjs controller I am making call to the DataService.getData() to make ajax call and hence set the returned dataObject within factoryobject 'data'
and I have declared it in controller like this
appV.data = DataService.data;
If I try to print it on console or access like this
console.log(appVm.data), I am able to access it, but if I try to access any subObjects like Ex - appVm.data.property1 or appVm.data.subObject1.subObject1.property, it gives undefined.
Can someone please explain why this behavior is occuring ?
Thanks in Advance
It is just example:
app.factory("messageService", function($q){
return {
getMessage: function(){
return $q.when("Hello World!");
}
};
});
And now the routing configuration that will use the service in a resolve.
$routeProvider
.when("/news", {
templateUrl: "newsView.html",
controller: "newsController",
resolve: {
message: function(messageService){
return messageService.getMessage();
}
}
})
These link may help you:
Link 1,
Link 2

AngularJS: Routes with Multiple resolves using Services are not firing

I am configuring an AngularJS app and am having a little trouble ensuring that my promises are firing before the controllers are loading. My understanding is that this can be done. A bit of code:
First, here's the router code:
$routeProvider
.when('/apage', {
controller: 'APageController',
templateUrl: 'app/apage/apage.view.html',
requiresLogin: true,
resolve: {
"data": function($q, data1Service, data2Service) {
var data1 = data1Service.getData();
var data2 = data2Service.getData();
return $q.all({
data1: data1.$promise,
data2: data2.$promise});
}
}
})
...
Here's one of the service functions (both are similar)...
function getData() {
var deferred = $q.defer();
$http(req)
.success(function(data, status, headers, config) {
// store data ...
deferred.resolve(1); // just a flag to say it worked
$rootScope.$apply();
})
.error(function(data, status, headers, config) {
deferred.resolve(0);
$rootScope.$apply();
});
return deferred.promise;
}
And here's the controller code...
angular
.module('app')
.controller('APageController', APageController);
APageController.$inject = [... 'data'];
function APageController(... data) {
var data1 = data.data1;
var data2 = data.data2;
...
All three are in different files but part of the same module. There must be some concept I'm overlooking. Is there anything apparent here to explain why my resolve promises are not firing?
Thank you.
If you pass in object literal to q.all it will resolve immediately. Instead pass array of promises so that it waits for it to resolve reject. Also .$promise is not needed in your case because you are already returning a promise from your service(based on the displayed code). $promise is generally attached by the object returned by $resource
i.e
return $q.all([data1Service.getData(),
data2Service.getData()]);
and expect data to be array of data resolved from above 2 calls.
or create 2 resolves:
resolve: {
"data": function($q, data1Service, data2Service) {
return data1Service.getData();
},
"data2": function($q, data1Service, data2Service) {
return data2Service.getData();
}
}
and inject data and data2.
otherwise, chain through and change the response format to expect the way you were originally trying to get.
resolve: {
"data": function($q, data1Service, data2Service) {
return $q.all([data1Service.getData(),data2Service.getData()])
.then(function(response){
return {
data1:response[0],
data2:response[1]
};
});
}
}
Do not place rootScope.apply inside your service, it will cause digest already in progress error (since angular will ). $http will automatically resolve it.
You just need this.
function getData() {
return $http(req);
}

angularJS services - return promise for retrieving data AND object for managing data?

I have a question regarding angularJS services.
From what I have read, there are two ways of using services.
[1] Have a service return a promise to return data. If you use this method, in your routeProvider, you can make sure Angular resolves this promise to return data BEFORE it loads the page.
e.g.
App.factory('BooksService', function($q, $http) {
var deferred = $q.defer();
$http.get('/rest/books').then(function(data) {
deferred.resolve(data);
}, function(err) {
deferred.reject(data);
});
return deferred.promise;
};
Then, in my route provider:
...
$routeProvider.when('/books', {
controller : 'BooksCtrl',
templateUrl: '/partials/books.html',
resolve: {
books: 'BooksService'
}
});
...
Then, in my controller:
App.controller('AddPaypalAccountCtrl', function($scope, BooksService) {
$scope.books = BooksService;
}
[2] Have a service return an object that contains functions and data.
e.g.
App.factory('BooksService', function($q, $http) {
var books = [];
var service = {
getBooks : function() {
return books;
},
addBook: function(book) {
books.push(book);
}
};
return service;
};
My question: Is it possible to get the best of both worlds and have a service return a promise that when resolves returns an object that contains functions and data?
I want the $http call to get the books to be resolved before I load the '/books' page, BUT I also want access to a service that can manage said books. Of course I can write two separate services, but I wonder if it's more efficient to keep them both in the same service and write a service that kills two birds with one stone like so:
Here's an example of my factory that returns a promise for retrieving the books.
App.factory('BooksService', function($q, $http) {
var books = [];
var service = {
getBooks: function() {
return books;
},
addBook: function(book) {
books.push(book);
}
}
var deferred = $q.defer();
$http.get('/books').then(function(data) {
books = data.data;
deferred.resolve(service);
, function(err){
deferred.reject(err);
});
return service;
};
Then, as per before, my route provider is as follows, requiring that books be retrieved before I go to the /books page:
...
$routeProvider.when('/books', {
controller : 'BooksCtrl',
templateUrl: '/partials/books.html',
resolve: {
books: 'BooksService'
}
});
...
Then, in my controller, I will attach books to the scope like so.
App.controller('AddPaypalAccountCtrl', function($scope, BooksService) {
$scope.books = BooksService.getBooks();
}
I haven't seen anyone do this yet, so I'm wondering if this is OK.
I feel you are trying to break the SRP - Single Responsibility Principle.
What is the Responsibility of your service?
Provide an API for async request or make the request?
If it provides API, it should not be loaded async.
If too make the request, it should be a method of the service, not the service itself. A service is the interface to your request, not the request!
Rarely you may need to get logic back from your server, but again, you have to separate concerns:
Get the logic (e.g. Angular expression as a string) from server.
Parse into a function performing the logic (can be done with Angular $parse service).
Inject your logic function wherever you need to use it.

Angular.js multiple rest calls scope issue

i'm a biginner when it comes to Angular.js, and i have a problem with $scope not getting additional value from one of two $resource rest calls. Here's my code:
controller: function ($scope, $modalInstance, $route) {
$scope.server = {}
$scope.submit = function () {
//AddNewServer is a $resource service
AddNewServer.post($.param({
'name': $scope.server.name,
'ip': $scope.server.ip,
'port': $scope.server.port
}));
//ServerStats is a $resource service
ServerStats.postServerStats(function success(data) {
$scope.server.bytesIn = data.returnValue.bytesIn
}, function err(err) {
console.log("Error: " + err)
})
$modalInstance.dismiss('cancel');
$route.reload()
//BELLOW LOG RETURNS Object {name: "asd", ip: "asd", port: 2} NO bytesIn
console.log($scope.server)
}
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
$route.reload()
};
}
Question is how do i add bytesIn from my other service call into my server object? I'm sure it a pretty obvious thing but i'm still in learning phase. Thanks in advance.
Your postServerStats() call is asynchronous, so it's likely that your success function isn't being called before the console.log($scope.server) statement.
Put console.log($scope.server) in your success function, after you assign $scope.server.bytesIn.
Perhaps you mean to do more work in your postServerStats() callback?
Or better yet, look into angular promises

$scope inside a callback of a resource get call will not work

i am having a problem accessing the $scope. as it seems it is not working for me.
i have a resource:
squashApp.factory('CourtsService', function($resource) {
return $resource('/api/court/:num', {num: '#num'});
});
and my controller does:
squashApp.controller('CourtsController',
function CourtsController($scope, $window, $http, CourtsService) {
CourtsService.get({num:1}, function(data){
$scope.courts = data;
})
});
my server succeeds in returing a data which is in format of javascript object (JSON).
i have checked it. but for some reason the $scope is not updated and after this callback my view is not changing at all.
help please
I created a demo for you and your code looks ok.
However, it is always good to add some logic for the callback when the error occurs like this, so your app will not die silently.
squashApp.controller('CourtsController', function CourtsController($scope, $window, $http, CourtsService) {
CourtsService.get({
num: 1
}, function (data) {
console.log('success');
$scope.courts = data;
}, function (data) { // -> error handling
console.log('failed');
$scope.courts = data;
})
});
Demo
A simple way to access your $scope using angular $resource by using $promise (recommended)
squashApp.controller('CourtsController',
function CourtsController($scope,CourtsService) {
CourtsService.get({num:1}).$promise.then(function(data){
//$scope -- can be accessed here
}, function(failed){
}
});

Categories