angular js - getting json data - javascript

I am trying to get data from json data so i write this:
app.factory('data', function($resource) {
return $resource('mock/plane_urls.json', {}, {
getTreeData: { method: 'GET', isArray: false }
})
})
and then using:
data.getTreeData.Carriers.Carrier;
Where Carriers is the first node in json file. but it doesnt work ;/ I got error
Error: data.getTreeData.Carriers is undefined

You are trying to reach into the Carriers object before it is fetched. Before the data comes back, Carriers is just an empty object.
You could do something like $scope.carriers = data.getTreeData(); and then in your view have an element with ng-repeat="carrier in carriers"
The idea behind $resource is that you get an empty object, so the view renders nothing. When the request is complete, the empty object is replaced and the view is re-rendered with the data automatically.
You could also use the $http service like so and provide a callback function that executes once the data is fetched.
$http.get('mock/plane_urls.json').then(function(data){
carrier = data.Carriers.Carrier
});
BUT! should break this into a service and a controller though. Just have the service getTreeData return the promise object like so: return $http.get('mock/plane_urls.json'); and then in your controller call it with then() and provide the callbacks for success and error:
getTreeData.then(
function(data){
carrier = data.Carriers.Carrier;
},
function(err){
console.log("Error: " + err);
});

You can use $scope.$watch to watch the value of the data.getTreeData.
When new data comes in, the callback will be called, then, you can get your data you want.
http://docs.angularjs.org/api/ng.$rootScope.Scope

Related

Asynchronous requests from angular

I have a method in service to get httprequest from another server and in the components console get null of value ollayer but data is not null
ollayer={};
service:
getLayer(): Observable<any> {
return this.http.get<olLayer>(
'http://localhost:3000/geomap/getlayer',
);
}
components:
this.olservice.getLayer().subscribe((data) => {
this.ollayer = data;
console.log(data)
});
console.log(this.ollayer)
That behaviour is fine, that's how asynchronous pipelines work.
For whatever reason you need the data, for example, to update a view on your web page, you have to do it in the subscribe scope. For example, you are updating this.ollayer inside the subscribe, so any view properly binded to that variable will update when the request is done.
Edit: it is ok for data being null on your second log because data may not have arrived yet. But it is not ok to be null on the log inside the subscribe.

How to retrieve data from mongoose sequentially?

get: function (code) {
console.log('Retrieving model for code : ', code);
let database = UTILS.getDatabase('databaseName');
return database.models.modelName.find({})
.then(function (users) {
console.log(' ----------- ', users);
return users;
})
.catch(function (error) {
return '{success: "false", msg: "Error found : ' + error + '"}';
});
}
This code is running without any errors, but the function that calls "get" couldn't find any record, while callback function prints around 8-9 records in console. I know this is callback functionality, but I need this to be happen sequentially.
I also tried to use yield return yield database.models.modelName.find({}) with * function, but getting {}, an empty object.
Please suggest a way to avoid callback and get data from mongodb.
Thanks Julien, but I can't use callback, because the function which is calling "get" has logic to process object return from mongoose.
Hi Ravi, here is complete flow of this process stack. Route -> Controller -> Facade -> Service -> Dao (the code I posted is belongs to Dao layer get function)
This looks typical typed language solution, but I need this to be in this way.
a Service layer function could collect data from multiple model and could be processed collectively, so callback process doesn't fulfill my requirement here.
I am completely stuck, Thanks for help :)
Router :
app.route('/nodics/users')
.get(CONTROLLER.UserController.get)
.post(CONTROLLER.UserController.set);
Controller:
get: function (request, response, error) {
let users = FACADE.UserFacade.get();
response.json(users);
}
Facade :
get: function (code) {
console.log('inside Facade call....', code);
return SERVICE.UserService.get(code);
}
Service :
get: function (code) {
console.log('inside Service call....', code);
return DAO.UserDao.get(code);
}
Dao method is already there at top. This is a sample layered implementation. but I just want to to be implemented in this way only. so that I can call, DAO layer method anytime and from anywhere in the Service layer.
Use Case:
1. I want to add one item into cart, so I pass, PID, SKUID and quantity to the router, which simply pass controls to controller.
2. Controller pass it to facade and Service.
3. In service layer
1. Call another service to check if quantity is valid
2. Call DAO to load product item
3. Call another DAO to load Inventory (or use from first call)
4. Call another DAO to load price item, based on local and currency, or other parameters.
5. Finally load ORDER and add this item into it and save it
6. Return order item to facade layer
4. In Facade, apply filter to return only fields required to expose as service.
So If I want to implement this use case, getting data by callback from mongoose will not help.
So please suggest me the way to get data directly from mongoose without using callback.
You need to pass a callback to your function and call it from your promises:
get: function (code, cb) {
console.log('Retrieving model for code : ', code);
let database = UTILS.getDatabase('databaseName');
return database.models.modelName.find({})
.then(function (users) {
console.log(' ----------- ', users);
cb(users);
})
.catch(function (error) {
cb({success: "false", msg: "Error found : ' + error + '"});
});
}

$resource usage in Angular.js [duplicate]

Let's say a service like this:
services.factory('User', function($resource){
return $resource('/rest/usersettings/:username', {}, {
get: {method: 'GET'},
update: {method: 'POST'}
});
});
So it is supposed to be used like this:
scope.user = User.get( {username: 'bob'} ); // GET
console.log( JSON.stringify(scope.user) ) // {"$promise":{},"$resolved":false}
So, when I send GET request, it goes OK, building this ur + params:
http://localhost:9000/rest/usersettings/bob
Question, why I have: {"$promise":{},"$resolved":false}
If my GET request leads to json-response back from the server:{"username":"bob","email":"bob#bobs.com"} then I'm expecting to have my scope.user filled by data.
Should I wait somehow promise is ready / resolved ?
User.get( {username: 'bob'} ) does not return your actual data immediately. It returns something will hold your data when the ajax returns. On that (the $promise), you can register an additional callback to log your data.
You can change your code to:
scope.user = User.get( {username: 'bob'} ); // GET
scope.user.$promise.then(function(data) {
console.log(data);
});
You will get your data in there, but not immediately.
Read the docs on ngResource:
It is important to realize that invoking a $resource object method
immediately returns an empty reference (object or array depending on
isArray). Once the data is returned from the server the existing
reference is populated with the actual data. This is a useful trick
since usually the resource is assigned to a model which is then
rendered by the view. Having an empty object results in no rendering,
once the data arrives from the server then the object is populated
with the data and the view automatically re-renders itself showing the
new data. This means that in most cases one never has to write a
callback function for the action methods.
For now I use this (it seems I duplicate this question )
User.get({
username: 'bob'
}, function(user) {
user.$update(
function(data, headers) {
console.log("GOOD");
},
function(err, headers) {
console.log("BAD");
}
);
});
This should work :
User.get( {username: 'bob'} ).$promise.then(function(data) {
scope.user = data.toJSON();
});
toJSON() cleans up Angular's internal properties ($$).

Why does angular $resource add extra objects ($promise, $resolve...) to my data response?

I return a resource with a URL
$resource("http://foo.com/bar.json").get().
$promise.then(function(data){ $scope.result = data},
function(error){ $scope.msg = "error" } );
Resource returns
["item1"...."item_n",.....,"$promise", "$resolved", "$get", "$save", "$query", "$remove", "$delete"]
Why do I get all those objects in my data set. I'm guessing $promise just returns all this and waits for the server response. But once I have the server response where can I just get my server data without the Promise jargon?
If you look at the angular source here:
https://github.com/angular/angular.js/blob/master/src/ngResource/resource.js#L505
There is a toJSON method on the Resource prototype chain that will accomplish this for you.
For example:
$resource("http://foo.com/bar.json").get(function(res) {
$scope.result = res.toJSON();
});
You need to return wrapped result like {'result': { 'some_key': 'some_val' }} from your backend.
Or just do like described above.
Diary.getSharedWithMe(function(data) {
delete data.$promise;
delete data.$resolved;
_self.sharedDiariesWithMe = data;
}, function(error) {
console.log(error)
});
$resource returns an object or array that will have your data when the call completes. All those functions are there to help you out and $resource is mainly intended for CRUD operations. If you want the data, you have to wait for it to get returned so you might as well use the promise. If you want to strip all of those properties you can use angular.toJson to convert it to json, but angular does that for you when posting it back to a resource or $http call so you shouldn't have to.
$scope.data = $resource("http://foo.com/bar.json").get();
// $scope.data does not have your data yet, it will be
// populated with your data when the AJAX call completes
...
// later in a call from a save button maybe you can just do
// this to post your changes back:
$scope.data.$save();
So in case someone else is stumbling here and didn't understand promises/angularjs here is what is going on. When you use .then() or .get() you get a promise and some helper functions all in the same object. This is awesome because then you don't worry about callbacks being defined and whether data is available because the promise object always has some properties. This object contains your raw data in another object within. So the promise object is nested, you just have to reference the data object within when the data is ready.
Here's what I was doing
$resource("http://foo.com/bar.json").get().
$promise.then(function(data){ $scope.result = data},
//data is actually a promise object.
function(error){ $scope.msg = "error" } );
promise object
Note the data is actually under another object called "data". So in your success callback to get just the data you should do in this case: data.data
To automatically remove them from every request, you can add an interceptor:
angular.module('app').config(config);
config.$inject = ['$httpProvider'];
function config($httpProvider) {
$httpProvider.interceptors.push(interceptor);
}
interceptor.$inject = [];
function interceptor() {
return {
request: (config) => {
if (config.data) {
delete config.data.$promise;
delete config.data.$resolved;
}
return config;
}
};
}

Javascript Object appears then disappears Angular Js

I have created a factory which does a HTTP get to a php script.
The php script returns the proper data to the factory which then sends its data to the controller:
.controller('CatListController', ['$scope', 'Category', function ($scope, Category) {
$scope.categories = {};
var res = Category.list();
console.log(res); // <-- shows the proper object
console.log(res.data); //<-- shows nothing
if (res.error) {
$scope.error = true;
$scope.message = "http error";
}else{
if (res.data.error) {
$scope.error = true;
$scope.message = "database error";
}
$scope.categories = res.data;
}
}]);
the first console log displays the full object in its entirety, but the next console log display an empty object.
the object that is supposed to shown is (and does from the console log res):
{
data: { name: "" },
error: false
}
why is this happening?
I guess it is all right! Your first console.log prints an object. The browser keeps the output up to date with the state of the object. Keep in mind list() ist an asynchronous call, so the result will arrive later. The second console.log output prints a property of the object. The console did not update this if the data are arriving.
From the angular $ressource documentation:
It is important to realize that invoking a $resource object method immediately returns an empty reference (object or array depending on isArray). Once the data is returned from the server the existing reference is populated with the actual data. This is a useful trick since usually the resource is assigned to a model which is then rendered by the view. Having an empty object results in no rendering, once the data arrives from the server then the object is populated with the data and the view automatically re-renders itself showing the new data. This means that in most cases one never has to write a callback function for the action methods.

Categories