How to traverse this json object in Angular js? - json

I have this object received from the server:
Resource {$promise: Promise, $resolved: false, $get: function, $save: function, $query: function…}
$promise: Promise
$resolved: true__v:
_id: "54ed85a92908cc9c0cce7044"
about: "about"
amenities: Array[0]
length:
__proto__: Array[0]
created: "2015-02-25T08:19:53.790Z"
direction: ""
images: Array[2]
location: "lkj"
name: "resort3"
path: "uploads/projects/ASH_RESORT002"
profile_pic: "uploads/projects/ASH_RESORT002/images/2013-05-18-1452.jpg"
resort_id: "ASH_RESORT002"
room_count:
user: Object
__proto__: Resource
I am able to access the $promise and $resolved items in json using obj.$promise and $.resolved respectively. But I am unable to access the non dollar items like "images" by doing obj.images or obj.resort_id
BTW the same items are accesible in the view when used against ng-model. Something like ng-model="obj.resort_id" is successfully binding.
Please guide!

You aren't including the code that retrieves, or logs, this resource, so I'm taking a bit of a guess here. You may be running into a side-effect of console.log(). That function is asynchronous - it doesn't instantly log the "current" values of the object. However, object property access attempts ARE instant. It's possible your object looks 'resolved' when you console.log() it (because it IS, by the time that does its work) but accessing a property directly is looking at an object that is not yet resolved. You can confirm this by console.log()'ing the $resolved property.
The documentation for $resource contains the appropriate solution:
var User = $resource('/user/:userId', {userId:'#id'});
User.get({userId:123}).$promise.then(function(user) {
// access user.value here.
});
That is, you can't access User.* immediately after calling .get(). You need to "then" the promise and let it resolve.

Related

How to pass Pulumi's Output<T> to the container definition of a task within ecs?

A containerDefinition within a Task Definition needs to be provided as a single valid JSON document. I'm creating a generic ECS service that should handle dynamic data. Here is the code:
genericClientService(environment: string, targetGroupArn: Output<string>) {
return new aws.ecs.Service(`${this.domainName}-client-service-${environment}`, {
cluster: this.clientCluster.id,
taskDefinition: new aws.ecs.TaskDefinition(`${this.domainName}-client-${environment}`, {
family: `${this.domainName}-client-${environment}`,
containerDefinitions: JSON.stringify(
clientTemplate(
this.defaultRegion,
this.domainName,
this.taskEnvVars?.filter((object: { ENVIRONMENT: string }) => object.ENVIRONMENT === environment),
this.ecrRepositories
)
),
cpu: "256",
executionRoleArn: taskDefinitionRole.arn,
memory: "512",
networkMode: "awsvpc",
requiresCompatibilities: ["FARGATE"],
}).arn,
desiredCount: 1,
...
There is a need of information from an already built resource this.ecrRepositories which represents a list of ECR repositories needed. The problem here is that let's say you want to retrieve the repository URL and apply the necessary 'apply()' method, it will return an Output<string>. This would be fine normally, but since containerDefinitions needs to be a valid JSON document, Pulumi can't handle it since JSON on an Output<T> is not supported;
Calling [toJSON] on an [Output<T>] is not supported. To get the value of an Output as a JSON value or JSON string consider either: 1: o.apply(v => v.toJSON()) 2: o.apply(v => JSON.stringify(v)) See https://pulumi.io/help/outputs for more details. This function may throw in a future version of #pulumi/pulumi.
Blockquote
Neither of the suggested considerations above will work as the dynamicly passed variables are wrapped within a toJSON function callback. Because of this it won't matter how you pass resource information since it will always be an Output<T>.
Is there a way how to deal with this issue?
Assuming clientTemplate works correctly and the error happens in the snippet that you shared, you should be able to solve it with
containerDefinitions: pulumi.all(
clientTemplate(
this.defaultRegion,
this.domainName,
this.taskEnvVars?.filter((object: { ENVIRONMENT: string }) => object.ENVIRONMENT === environment),
this.ecrRepositories
)).apply(JSON.stringify),

Parse a json object shows undefined

I was using OMDBapi to get the details of different movies. I successfully fetched the result and it returns a json object like this;
{"Title":"WWA: The Inception","Year":"2001","Rated":"N/A","Released":"26 Oct 2001","Runtime":"N/A","Genre":"Action, Sport","Director":"N/A","Writer":"Jeremy Borash","Actors":"Bret Hart, Jeff Jarrett, Brian James, David Heath","Plot":"N/A","Language":"English","Country":"Australia","Awards":"N/A","Poster":"https://m.media-amazon.com/images/M/MV5BNTEyNGJjMTMtZjZhZC00ODFkLWIyYzktN2JjMTcwMmY5MDJlXkEyXkFqcGdeQXVyNDkwMzY5NjQ#._V1_SX300.jpg","Ratings":[{"Source":"Internet Movie Database","Value":"6.0/10"}],"Metascore":"N/A","imdbRating":"6.0","imdbVotes":"22","imdbID":"tt0311992","Type":"movie","DVD":"N/A","BoxOffice":"N/A","Production":"N/A","Website":"N/A","Response":"True"}
Note that we get this type of object from the api if we want to get a particular movie details and that is what i was doing. Now to show the different details to a user, i started parsing this JSON object which works fine but when i try to get the value of the Value key present inside the Ratings key, it returns undefined.
I am working with react-native. After getting the data, i stored it inside the state, named it as details. Then to get it;
this.state.details.Title //if i wanted to get the Title and it works fine.
Then for Value inside Ratings;
this.state.details.Ratings[0].Value
But it returns undefined.
Also note that this works fine in pure Javascript as i parsed the dict in the browser console in the same way and it returned the correct value.
Here is more code;
componentDidMount() {
this.fetchData();
}
fetchData = async () => {
const response = await fetch(`http://www.omdbapi.com/?i=${this.props.navigation.getParam('i')}&apikey=******`) // where this.props.navigation.getParam('i') is the omdbid of the movie
const result = await response.json()
this.setState({details: result})
}
Here is error log;
undefined is not an object (evaluating 'this.state.details.Ratings[0]')
You're most likely trying to access state object before fetch has done it's job .... it's an async op ... so you should make sure your data is ready before rendering...
if (this.state.details) {
// start rendering...
}
More Explanation
your setState function should be executed right after fetch has finished its job, and since it's an async operation, it's going to take some time ...During that time, render function is executed with no state.details --> causing your issue ...
That's why you should check for state before rendering ... besides, the optional chaining trick Silversky Technology mentioned in his answer
If the value property you are accessing from the object might be not available for all the movies in the data you are getting from API response so it might cause you to error when accessing key from undefined objects.
To overcome the issue there is a way, you can try a fix as below:
this.state.details.Ratings[0]?.Value
The ? symbol lets the javascript not give an error when the value key not available in the object. it will make the accessing of property optional.
When storing objects in states it often causes problems as you are doing in line
this.setState({details: result})
Save result after strigifying it like
JSON.stringify(result)
this.setState({details: result})
Then when fetching form state, parse it back to object by
var result = JSON.parse(this.state.details)
Then you should be able to access it
You can access Ratings[0].Value by
this.state.details.Ratings && this.state.details.Ratings[0].Value
like,
<Text> {this.state.details.Ratings && this.state.details.Ratings[0].Value} </Text>

Difficult reading JSON and add ng-repeat list list is not completed $ http $$ HashKey

I am new to Angle and am finding it very nice, my problem is this:
have a ng-repeat running straight when caught the data source of a variable javascript like this:
var alertsq = [
{
"alert":"mediun",
"nt":"28",
"nu":"28",
"no":"34",
"dtini":"2012/Jul/23",
"no":"3",
"dtoc":"23/7/2012",
"dtuo":"25/7/2012",
"id":"227529436529033216",
"msg":"Uh oh, this could be bad. Check the door lock vendor before you book you next hotel room: http://example.co/n56emZf2"
},
{
"alert":"mediun",
"nt":"28",
"nu":"28",
"no":"34",
"dtini":"2012/Jul/23",
"no":"3",
"dtoc":"23/7/2012",
"dtuo":"25/7/2012",
"id":"227529436529033216",
"msg":"Uh oh, this could be bad. Check the door lock vendor before you book you next hotel room: http://example.co/n56emZf2"
}];
My controller that takes the variable alertsq and arrow on the scope is as follows:
app.controller("alertsController",function(){
console.log(alertsq);
this.alerts =alertsq;
});
The cool thing is that it works and my list in *ng-repeat* is filled beautifully, but when I use the $http to load a JSON content of a file does not meet the same list: O controller code is so :
app.controller("alertsController", function($http,$scope){
$http({
url: "data/alerts.json",
dataType: "json",
method: "GET",
headers: {
"Content-Type": "application/json"
}
}).success(function(data){
$scope.alerts= data;
console.log($scope.alerts);
}).error(function(error){
console.log(data);
console.log(error);
});
});
The cool thing is that JSON is coming just right the browser output in the first case
that the list is filled is as follows:
mainController controller.js:7
[Object, Object, Object, Object, Object, Object, Object]
0: Object
$$hashKey:"object:4"
alert: "mediun"
dtini: "2012/Jul/23"
dtoc: "23/7/2012"
dtuo: "25/7/2012"
id: "227529436529033216"
msg: "Uh oh, this could be bad. Check the
door lock vendor before you book you next hotel room:
http://example.co/n56emZf2"
no:"3"
nt: "28"
nu: "28"__proto__:
Object1:
Object2:
And this is the console output when I seek for $http JSON:
[Object, Object, Object, Object, Object, Object, Object]
0: Object
alert: "mediun"
dtini: "2012/Jul/23"
dtoc: "23/7/2012"
dtuo: "25/7/2012"
id: "227529436529033216"
msg: "Uh oh, this could be bad. Check the
door lock vendor before you book you next hotel room:
http://example.co/n56emZf2"
no:"3"
nt: "28"
nu: "28"__proto__:
Object1:
Object2:
The detail is that the output obtained by the JSON via $http there is no attribute $$HashKey, and so the list in the ng-repeat is not filled :(, can anyone help me solve this?
When you updated your controller constructor function to include $http, you also added $scope. Changing from inferred to explicit dependency injection could be a problem for several reasons.
For example, the following html will display the alerts using your original controller.
<div ng-controller="CtrlOne as vm">
<div ng-repeat="alert in vm.alerts">
{{alert.alert}} - {{alert.msg}}
</div>
</div>
However, your updated controller (in which you inject $scope explicitly) won't work with the "controller as" syntax. The controller alias must be removed to be compatible with your new controller constructor function:
<div ng-controller="CtrlOne">
<div ng-repeat="alert in alerts">
{{alert.alert}} - {{alert.msg}}
</div>
</div>
Here's a demo of both methods: http://plnkr.co/edit/TrTFV36kQ8Llz3n2NChB?p=preview
Alternatively, you can remove $scope from the dependency injection, and go back to using this.alerts in the controller.

Sencha Touch's proxy's reader's rootProperty and Parse.com's REST API response

My backend is Parse.com's REST API, and parse send me back a results object that looks like:
{
...fields...
}
when there is only object, meaning any time there is a create, a read or an update to one record. When I GET a collection of objects from Parse, it sends out a results object that looks like:
{
results: [
{
...fields...
}
]
}
In ST, when I have my proxy's reader's rootProperty set to: 'results', my reader isn't able to read the record Parse sends on a create or an update and therefore the local record doesn't get synced with the one the server sent.
When I have my reader's rootProperty set to: '', my local record gets synced with the one that Parse sent, but now my list, which takes a store, isn't displaying the list of records, because Parse sends that with a "results" node.
I tried using setRootProperty, but despite confirming that the reader's root property just before calling save() on a record is in fact: '', the local record doesn't sync with Parse's response. As soon as I remove the logic that does real time changes to root property, it starts working again.
What is the suggested way of handling this situation? Any help is much appreciated! Thanks!
So you have one store with a proxy that has a certain rootProperty but you olso have 2 type of response, single object or an array of objects inside results. If it is so, definitly your proxy is able to read only one type of response.
Some solutions:
-if you can operate on server make sure you send always an array of results whether the response contains none, one or many results.
-implement a custom reader (this is what i did when i had to manage different responses and make some changes on data in the meanwhile)
Ext.define('MyApp.store.MyStore',{
extend:'Ext.data.Store',
model:'MyApp.model.MyModel',
proxy: {
type:'jsonp',
url:'#'
},
autoLoad:false,
loadSolr:function(PARAMS){
this.groupField = groupField;
Ext.data.JsonP.request({
scope:this,
url: 'http://myserver.com',
callbackKey: 'json.wrf',
params: {
PARAMS
},
success: function(response) {
// handle your response here
var records = [];
Ext.each(response.results, function(record){
records.push({
field1: record.field1,
field2: record.field2
});
});
//load your data into store
this.loadData(records);
}
});
}
});
Hope it helps, post some code if i misunderstood something

How to get a list via POST in Restangular?

Consider a REST URL like /api/users/findByCriteria which receives POSTed JSON that contains details of the criteria, and outputs a list of Users.
How would one call this with Restangular so that its results are similar to Restangulars getList()?
Restangular.all('users').post("findByCriteria", crit)... might work, but I don't know how to have Restangular recognize that the result will be a list of Users
Restangular.all('users').getListFromPOST("findByCriteria", crit)... would be nice to be able to do, but it doesn't exist.
Doing a GET instead of a POST isn't an option, because the criteria is complex.
Well,
I experience same problem and I workaround it with plain function, which return a plain array of objects. but it will remove all Restangular helper functions. So, you cant use it.
Code snippet:
Restangular.one('client').post('list',JSON.stringify({
offset: offset,
length: length
})).then(
function(data) {
$scope.clients = data.plain();
},
function(data) {
//error handling
}
);
You can get a POST to return a properly restangularized collection by setting a custom handler for OnElemRestangularized in a config block. This handler is called after the object has been Restangularized. isCollection is passed in to show if the obect was treated as a collection or single element. In the code below, if the object is an array, but was not treated as collection, it is restangularized again, as a collection. This adds all the restangular handlers to each element in the array.
let onElemR = (changedElem, isCollection, route, Restangular: restangular.IService) => {
if (Array.isArray(changedElem) && !isCollection ) {
return Restangular.restangularizeCollection(null, changedElem, changedElem.route);
}
return changedElem;
};
RestangularProvider.setOnElemRestangularized(onElemR);