React - iterating through JSON object - json

I am new to Javascripting and React JS coding. I have this JSON object-
var json1 = {"facilities":{"facility":[{"facilityCode":"J0LN","facilityId":"1","facilityName":"J0LN","npid":"1295718450","pid":"123457","providerState":"Alabama"},{"facilityCode":"K0NS","facilityId":"2","facilityName":"K0NS","npid":"9696969669","pid":"111111","providerState":"Alaska"},{"facilityCode":"J0LN1","facilityId":"3","facilityName":"J0LN1","npid":"111111111","pid":"221133","providerState":"Alabama"},{"facilityCode":"0987654321","facilityId":"4","facilityName":"0987654321","npid":"0987654321","pid":"235675","providerState":"Alabama"},{"facilityCode":"7776667676","facilityId":"5","facilityName":"7776667676","npid":"7776667676","pid":"236576","providerState":"Alabama"},{"facilityCode":"979797977","facilityId":"6","facilityName":"979797977","npid":"979797977","pid":"325347","providerState":"Alabama"},{"facilityCode":"9898989898","facilityId":"7","facilityName":"9898989898","npid":"9898989898","pid":"989898","providerState":"Alabama"},{"facilityCode":"121212","facilityId":"8","facilityName":"121212","npid":"1212120022","pid":"121212","providerState":"Connecticut"},{"facilityCode":"141414","facilityId":"9","facilityName":"141414","npid":"1414140022","pid":"141414","providerState":"Delaware"},{"facilityCode":"887766","facilityId":"10","facilityName":"887766","npid":"8877660022","pid":"887766","providerState":"Delaware"},{"facilityCode":"212121","facilityId":"11","facilityName":"OP-212121-OP","npid":"2121210022","pid":"212121","providerState":"Maryland"},{"facilityCode":"717171","facilityId":"12","facilityName":"IP-Qrtly-717171","npid":"7171710022","pid":"717174","providerState":"Alabama"},{"facilityCode":"RMC","facilityId":"13","facilityName":"RMC","npid":"1","pid":"676767","providerState":"Alabama"},{"facilityCode":"WCC","facilityId":"14","facilityName":"WCC","npid":"2","pid":"454676","providerState":"Alabama"},{"facilityCode":"FC","facilityId":"15","facilityName":"FN","npid":"1992813240","pid":"123456","providerState":"Alabama"},{"facilityCode":"VCC","facilityId":"16","facilityName":"VCC","npid":"1213121312","pid":"122312","providerState":"Alabama"},{"facilityCode":"AAAAA","facilityId":"17","facilityName":"AAAAA","npid":"3","pid":"112233","providerState":"Alabama"},{"facilityCode":"AAAAB","facilityId":"18","facilityName":"AAAAB","npid":"4","pid":"334455","providerState":"Alabama"},{"facilityCode":"AAAAC","facilityId":"19","facilityName":"AAAAC","npid":"5","pid":"556677","providerState":"Alabama"},{"facilityCode":"AAAAD","facilityId":"20","facilityName":"AAAAD","npid":"6","pid":"778899","providerState":"Alabama"},{"facilityCode":"AAAAE","facilityId":"21","facilityName":"AAAAE","npid":"7","pid":"616161","providerState":"Alabama"},{"facilityCode":"AAAAF","facilityId":"22","facilityName":"AAAAF","npid":"8","pid":"626262","providerState":"Alabama"},{"facilityCode":"AAAAG","facilityId":"23","facilityName":"AAAAG","npid":"9","pid":"717171","providerState":"Alabama"},{"facilityCode":"AAAAH","facilityId":"24","facilityName":"AAAAH","npid":"10","pid":"727272","providerState":"Alabama"},{"facilityCode":"AAAAI","facilityId":"25","facilityName":"AAAAI","npid":"11","pid":"757575","providerState":"Alabama"},{"facilityCode":"AAAAJ","facilityId":"26","facilityName":"AAAAJ","npid":"12","pid":"767676","providerState":"Alabama"},{"facilityCode":"AAAAK","facilityId":"27","facilityName":"AAAAK","npid":"13","pid":"818181","providerState":"Alabama"},{"facilityCode":"AAAAL","facilityId":"28","facilityName":"AAAAL","npid":"14","pid":"828282","providerState":"Alabama"},{"facilityCode":"AAAAM","facilityId":"29","facilityName":"AAAAM","npid":"15","pid":"858585","providerState":"Alabama"},{"facilityCode":"AAAAN","facilityId":"30","facilityName":"AAAAN","npid":"16","pid":"868686","providerState":"Alabama"},{"facilityCode":"AAAAO","facilityId":"31","facilityName":"AAAAO","npid":"17","pid":"919191","providerState":"Alabama"},{"facilityCode":"AAAAP","facilityId":"32","facilityName":"AAAAP","npid":"18","pid":"929292","providerState":"Alabama"},{"facilityCode":"AAAAQ","facilityId":"33","facilityName":"AAAAQ","npid":"19","pid":"959595","providerState":"Alabama"},{"facilityCode":"AAAAR","facilityId":"34","facilityName":"AAAAR","npid":"20","pid":"969696","providerState":"Alabama"},{"facilityCode":"UNIQUE","facilityId":"35","facilityName":"UNIQUE","npid":"21","pid":"123456","providerState":"Alabama"}]}};
I am setting the state of my data here and binding it (not sure why I am doing this, but I see everyone doing it as part of their ajax calls)
var stateSet = function(data) {
this.setState({data: json1});
};
stateSet.bind(this); // attempt to mock an AJAX call here, by assuming we have already obtained the JSON object.
return(
<table>
<tbody>
<tr>
<th>Facility Code</th>
<th>Facility ID</th>
<th>Facility Name</th>
<th>NPID</th>
<th>PID</th>
<th>Provider State</th>
</tr>
{
this.state.data.map(function(facility, key) {
// I'm not sure if the control is entering this function, and I don't understand why
return (
<tr>
<td>{facility.facilityCode}</td>
<td>{facility.facilityId}</td>
<td>{facility.facilityName}</td>
<td>{facility.npid}</td>
<td>{facility.pid}</td>
<td>{facility.providerState}</td>
</tr>
);
})
}
</tbody>
</table>
);
As I've mentioned in the code as part of the comment, I don't think the control is entering this.state.data.map(function(facility, key) { function and I don't understand why.

You're not targeting the facility array correctly.
It should be this.state.data.facilities.facility.map, and you may also set your json1 to state in your constructor directly like so
constructor() {
super();
var json1 = {
facilities: {
facility: [
{
facilityCode: "J0LN",
facilityId: "1",
facilityName: "J0LN",
npid: "1295718450",
pid: "123457",
providerState: "Alabama"
} ....
]
}
};
this.state = {
data: json1
};
}
Working Snippet

You path to array in incorrect, also add a check on availability of this.state.data so that it doesn't fail if data is not available,
{this.state.data && this.state.data.facilities.facility.map(function(facility, key) {}}

You re are use a map function on an object that has only on prop, this is not possible. The only prop the json object has is facilities

var stateSet = function(data) {
this.setState({data: json1});
};
why are you using function(date), this is not needed. Just give function(), because i think the stateSet is firstly not called anywhere so it doesn t get triggerd and you re expecting a prop in that function.

From your question, it is clear that you are trying to access the facility array inside the facilities object.
You can achieve this as:
this.state.data.facilities.facility.map((elementOffFacilityArray,index) =>
{
// do whatever you would like to do with individual elements of the array.
})
But at the time when this map function will execute, it might be the case that this facility array may be empty which will result in error whic already has been pointed out by #nrgwsth. Thus, you will have to keep the check and the above expression for this case will become as :
{
this.state.data &&
this.state.data.facilities &&
this.state.data.facilities.facility ?
this.state.data.facilities.facility.map((elementOffFacilityArray,index) =>
{
// do whatever you would like to do with individual elements of
the array.
})
:
''
}

Related

Rendering data from HTTP POST Angular 8

I'm kinda new to Angular and I need to do a function that does an http.post on click and it works (POST DONE is returned and I get the data), the problem is that i need to render data inside tables but 'postReponse' returns only [Object Object] in my html file and I can't find a way to render the data as it should, does anyone have a fix for this issue please ?
Here's the code sample :
public postReponse: any;
postRefs(){
return this.httpClient.post('someUrl',
{
"someBody"
})
.subscribe(
data => {
console.log("POST DONE", data)
return this.postResponse = data;
},
error => {
console.log("ERROR POST", error)
}
)
}
//home.component.html
<tr>
<td>{{postResponse}}</td>
<td>{{postResponse}}</td>
<td>{{postResponse}}</td>
<td>{{postResponse}}</td>
</tr>
postResponse is an object with keys and values, for example if it contains two attributes id and name then it will look like this :
{ id : 1, name = 'name' }
So if you need to access to the name attribute you need to write inside your html:
<td>{{postResponse.name}}</td>

Should I convert JSON to Array to be able to iterate it with v-for?

In the following code I am getting data from server and filling array with them:
Vue.http.post('/dbdata', DataBody).then((response) => {
App.$refs.userContent.rasters_previews_list.$set(response); // putting JSON answer to Component data in userContent
console.log("App.$refs.userContent.rasters_previews_list: ", App.$refs.userContent.rasters_previews_list.length);
}, (response) => {
console.log("Error")
});
Now I am filling. data is declared in var userContent = Vue.extend({. I am using App.$refs.userContent.rasters_previews_list to set it's value, because one man from SO said that there is no other way to get access to constructor. I tried to do output of rasters_previews_list after changing with watch, but here is what I am see. http://img.ctrlv.in/img/16/08/04/57a326e39c1a4.png I really do not understand am I setting it's right way or no. If yes, why I do not see data and see only this crap?
data: function () {
return {
rasters_previews_list: []
}
}
But How I can iterate it with v-for?
<ul v-for="img in rasters_previews_list">
<li>{{img}}</li>
<ul>
This code is display one bullet. So it's look like it's assume that there is one object.
My object in browser console look like:
Object {request: Object, data: Array[10], status: 200, statusText: "OK", ok: true}
Your setting the full response instead of just the data you actually need.
Vue.http.post('/dbdata', DataBody).then((response) => {
App.$refs.userContent.rasters_previews_list.$set(response.data);
console.log("App.$refs.userContent.rasters_previews_list: ", App.$refs.userContent.rasters_previews_list.length);
}, (response) => {
console.log("Error")
});
If this isn't what you are looking for please post a full example.

Reaching a specific property of the data json object

I would like to reach a specific property of the data that I have returned from my service.
So basically I want to be able to somehow reach $scope.users.name, I know that the users are the objects in the array, but could I reach that specific property in any way? Hopefully the question is clear enough?
$scope.users = [];
UserService.getAll().then(
function (data) {
$scope.users = data;
}, function (err) {
console.log(err);
}
);
I am assuming the data you receive is in the form of an array. If you know the index then you can do
$scope.users[2].name
Where 2 is the index of the object you want to know the name property of.
Or you can try a js function forEach
$scope.users.forEach(function (user) {
console.log(user.name);
});
The function will iterate over all the objects and you can access their properties inside the callback which is passed in.
Hope that is what you're looking for.

VueJS - trouble understanding .$set and .$add

I am trying to build an array of objects in VueJS and I am running into some issues with .$set and .$add.
For example, I need the following structure when adding new items/objects:
{
"attendees": {
"a32iaaidASDI": {
"name": "Jane Doe",
"userToken": "a32iaaidASDI",
"agencies": [
{
"name": "Foo Co"
}
]
}
}
}
New objects are added in response to an AJAX call that returns JSON formatted the same as above. Here is my Vue instance:
var vm = new Vue({
el: '#trainingContainer',
data: {
attending: false,
attendees: {}
},
methods: {
setParticipantAttending: function(data)
{
if (data.attending)
{
this.attendees.$add(data.userToken, data);
} else {
this.attendees.$delete(data.userToken);
}
}
}
});
This only works if I start with attendees: {} in my data but when I try attendees.length after adding an attendee, I receive undefined. If I use attendees: [], the new object does not appear to be added. And lastly, if I use .$set(data.userToken, data) it does not add in the 'token':{data..} format required.
What could be the issue here? What is the correct way to use $.add when starting with an empty array of objects?
UPDATE
I found that it works if I set attendees: {} and then, when adding a new object,
if (data.userToken in this.attendees) {
this.attendees.$set(data.userToken, data);
} else {
this.attendees.$add(data.userToken, data);
}
Not sure if there is a better way to accomplish this.
If you set attendees to an empty object ({}) it will not have a length attribute. That attribute is on Arrays.
If you set attendees to an empty array ([]) then you need to use $set (or really, I think you want .push()) – $add is intended for use on objects not on arrays.
I'm not quite following your last question – could you add more context?
EDIT 2:
The answer below was for Vue 1.x. For Vue 2.x and greater use:
this.$set(this.attendees, data.userToken, data);
More information here: https://v2.vuejs.org/v2/api/#Vue-set
EDIT:
Responding to your update, you should be able to just use $set in all cases. I.e. just do this:
this.attendees.$set(data.userToken, data);
As of version 0.6.0, this seems to be the correct way:
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })
http://vuejs.org/guide/reactivity.html#Change_Detection_Caveats

Backbone model .toJSON() doesn't work after .fetch()

Good day! I need to render a model's attributes to JSON so I can pass them into a template.
Model:
var UserInfo = Backbone.Model.extend({
url: appConfig.baseURL + "users/",
});
Template:
<script type="text/html" class="template" id="profile-form">
<h2 class="ui-li-heading"><%= username %></h2>
<p class="ui-li-desc"><strong><%= phone %></strong></p>
</script>
View:
var ProfilePageView = Backbone.View.extend({
events: {
'click #edit': "edit"
},
initialize: function () {
this.template = $.tpl['profile-form'];
var user = new UserInfo()
user.fetch({
data: $.param({email: localStorage.getItem('user_email')}),
type: 'POST'
});
console.log(user) //returns correct object with attrs
console.log(user.toJSON()) //returns empty object
},
render: function (eventName) {
$(this.el).html(this.template());
},
edit: function () {
window.workspace.navigate('#account/edit', { trigger: true});
}
});
When i put in console something like this, user.toJSON() returns correct data
var user = new UserInfo();
user.fetch({
data: $.param({email: localStorage.getItem('user_email')}),
type: 'POST'
});
But when i put it to my view, its returns Object {}.
Where is a mistake or tell me how can differently pass to the template data received from the server in json format? Thanks!
You appear to have two problems. fetch is asyncronous, so you need to use a callback to use the information. But first, an explanation about toJSON. .toJSON() doesn't actually return a JSON string, it returns an object that is what you want JSON to stringify. This allows you to modify the toJSON method to customize what attributes will be taken from your model or collection and added to the JSON string representation of your model. Here is a quotation from the Backbone.js docs:
toJSON collection.toJSON([options])
Return a shallow copy of the model's attributes for JSON
stringification. This can be used for persistence, serialization, or
for augmentation before being sent to the server. The name of this
method is a bit confusing, as it doesn't actually return a JSON string
— but I'm afraid that it's the way that the JavaScript API for
JSON.stringify works.
So you should replace this line in your code
console.log(user.toJSON())
with this one
console.log(JSON.stringify(user))
The object that you saw was returned by toJSON will then be turned into JSON.
Now, even after you do that, it won't work properly, because you will execute the console.log before you get the data for your model from fetch. fetch is asynchronous, so you need to call any code you want to be executed after the fetch is done in the success callback:
user.fetch({
data: $.param({email: localStorage.getItem('user_email')}),
type: 'POST',
success: function(){
console.log(user);
console.log(JSON.stringify(user));
}
});