I need to create a simple input words system, where WORDS are nested inside THEMES. The Json file MUST be like structured like this. And the file is dynamically populated. Here´s the Json code:
{"TEMAS":
{
"FRUTAS": {
"0": "ABACAXI",
"1": "JABUTICABA",
"2": "MEXERICA",
"3": "GOIABA"
},
"CARROS": {
"0": "FERRARI",
"1": "FUSCA",
"2": "HONDA",
"3": "MERCEDES"
},
"BRINQUEDOS": {
"0": "BOLA",
"1": "PIÃO",
"2": "BONECA",
"3": "CARRINHO",
"4": "TREM"
},
"JOGOS": {
"0": "XADREZ",
"1": "VIDEO GAME",
"2": "FUTEBOL",
"3": "QUEIMADA"
}
}}
My application needs to i.e. run inside "FRUTAS" then calculate its length and retrieve its values. Here's my code so far:
myApp.controller('catController', ['$scope', '$http', function ($scope, $http) {
$http.get('json/word_bank.json')
.success(function (result) {
$scope.themes = Object.keys(result.TEMAS);
var array = Object.keys(result).map(function (key) {
return result[key];
});
console.log(array);
})
.error(function (data, status) {
console.log(data);
});
$scope.category = '';
$scope.words = '';...
Someone can help?
Best Regards.
Sorry for explaining so bad the issue. The stack of my application is like this:
1 - An AngularJS app that takes several word inputs, wich updates a Json file. I cannot work with a database.
2 - I have to write the Json file with a variable sent by a HTML form.
What is my problem?
Read the Json, copy its data to something (e.g. an array), insert the data inside it, in the correct position. For example, the user write a new word "FOODS" that must enter on the same level as "JOGOS". I must update the json with that word. Then, the user will write another word "RICE" inside "FOOD", like "XADREZ" stands for "JOGOS". But i need the file to be updated, keeping the same structure, words, etc as before plus the new words. Was that clear?
How to do that? I dunno!
Related
I'm trying to use Postman as a test tool to validate that our customers all have a mailing address in our master system. I'm having trouble drilling down into the JSON due to its structure. Each response is an array structure with a single "node" that has no "head attribute" to address.
Example JSON:
[
{
"ID": "cmd_org_628733899",
"organization": {
"name": "FULL POTENTIAL",
"accountStatusCode": "1",
"accountStatusDescription": "OPEN"
},
"location": [
{
"locality": "LITTLE ROCK",
"locationType": "MAILING"
},
{
"locality": "BIG ROCK",
"locationType": "LOCATION"
}
]
}
]
Test code as it exists:
pm.test("Check for a Mailing Address", function () {
// Parse response body
var jsonData = pm.response.json();
// Find the array index for the MAILING Address
var mailingLocationIndex = jsonData.location.map(
function(filter) {
return location.locationType;
}
).indexOf('MAILING');
// Get the mailing location object by using the index calculated above
var mailingLocation = jsonData.location[mailingFilterIndex];
// Check that the mailing location exists
pm.expect(mailingLocation).to.exist;
});
Error message: TypeError: Cannot read property 'map' of undefined
I understand that I have to iterate to node(0) in the outer array and then drill into the nested location array to find an entry with a locationType = Mailing.
I can't get past the outer array. I'm new to JavaScript and JSON parsing - I am a COBOL programmer.
Knowing nothing else, I would say you mean this
pm.test("Check for a Mailing Address", function () {
var mailingLocations = pm.response.json().location.filter(function (item) {
return item.locationType === 'MAILING';
});
pm.expect(mailingLocations).to.have.lengthOf(1);
});
You want to filter out all the locations that have a MAILING type and there should be exactly one, or at least one, depending.
Whether pm.response.json() actually returns the object you show in your question is impossible to say from where I'm standing.
In modern JS, the above is shorter:
pm.test("Check for a Mailing Address", function () {
var mailingLocations = pm.response.json().location.filter(item => item.locationType === 'MAILING');
pm.expect(mailingLocations).to.have.lengthOf(1);
});
I have an object which is given back through my REST API and I need to iterate through it for synchronizing a DB. So the object contains another object called tables. The tables object has different arrays with table names and their key value pairs.
I could not loop through the tables object about two days whatever I did and it is really annoying getting null or undefined values back.
For example I tried iterating through the table array with the JavaScript function object.forEach((article)=>console.log(article.id,article.name));
const obj = response.content.tables.article;
function findArticles(obj) {
obj.forEach((article)=>console.log(article.id,article.name));
}
I can't get any value back. When I try to console.log(response.content); it shows me everything. As soon as I try to output response.content.tables it says undefined.
This is the structure of the object response.content:
{
"status": "1",
"message": "sync out request successfull",
"tables": {
"article": [
{
"id": 1,
"name": "baseball"
},
{
"id": 2,
"name": "truck"
},
],
"food": [],
"animals: []
}
}
Try converting the response to an object using JSON.parse(xyz) before attempting to get the properties.
var xyz = '{ "status": "1", "message": "sync out request successfull", "tables": { "article": [{"id": 1,"name": "baseball"},{"id": 2,"name": "truck"}],"food": [],"animals": []}}'
var obj = JSON.parse(xyz);
$(obj.tables).each(function (ix, el) {
console.log(el)
});
I solved it like this:
var obj = response.content;
var JSON = JSON.parse(obj);
var articleTable = JSON.tables.article;
articleTable.forEach((article)=>console.log(article.id,article.name));
After I parsed the response.content object to JSON it was available to access the nested objects as 'tables' and 'article'. After passing the article object with the articleTable variable to the forEach it has been possible to access each elements. Now I get results.
I really appreciate your help
T3.0 it wasn't able to solve the problem without you.
I am new to Ionic 3 & Angular and ran into an issue with *ngFor and .subscribe() method. Please forgive me if it is an easy question. I tried to figure out the behaviour of http.get(..).map(..).subscribe() function when used along with *ngFor to maintain an array of objects and show the records to user using *ngFor on the .html template file but unable to know *ngFor's odd behaviour.
In my Ionic 3 App, I am getting the data using an API and storing it inside a component variable called "users" which is declared as below in component .ts file -
users: Array<any>;
I have below component function which gives me data for this users array -
addUser(count: number) {
this.http.get('https://randomuser.me/api/?results=' + count)
.map(data => data.json().results)
.subscribe(result => {
for (let val of result) {
this.users.push(val);
}
})
}
Initially, I get data for 10 users from the API using above component function by simply calling it inside my ngAfterViewInit() function like -
this.addUser(10);
This gives me 10 user record objects inside my users array which I show to the user using something like below in the view .html file -
<ion-card *ngFor="let user of users">
{{user.email}}
</ion-card>
At this time *ngFor puts the last array element at first in the view and shows the records in the descending order as the elements in the array starting from index 9 to 0.(LIFO order)
Now I start popping the last element from this users array using users.pop(); and push another element at the beginning at index 0 by shifting current elements using users.unshift(..) in below function and calling it as addNewUser(1); -
addNewUser(count: number) {
this.http.get('https://randomuser.me/api/?results=' + count)
.map(data => data.json().results)
.subscribe(result => {
for (let val of result) {
this.users.unshift(val);
}
})
}
At this moment, if we consider the first array which had 10 elements, the last object at index 9 had been removed and another element at index 0 has been added making the previous elements on index 0-8 to shift to index 1-9.
On doing so, my view gets updated which has *ngFor and surprisingly this time it shows the first element at first place which is actually on index 0 which is the one I recently put. This is opposite to the order earlier followed by *ngFor to render elements on the screen.
Why *ngFor in Ionic 3 view shows the recently inserted object element first from the array of objects which is dependent on the subscribe method .subscribe() method. I am really confused about this.
I really need to clear the concept of *ngFor and subscribe(). Please help me.
Note : The API mentioned above is publicly accessible for testing and you may call it to check the response structure if required.
Pasting a sample API response below on calling https://randomuser.me/api/?results=1 -
{
"results": [
{
"gender": "male",
"name": {
"title": "mr",
"first": "daniel",
"last": "stoll"
},
"location": {
"street": "9719 tannenweg",
"city": "cottbus/chosebuz",
"state": "bremen",
"postcode": 81443
},
"email": "daniel.stoll#example.com",
"login": {
"username": "greenleopard994",
"password": "chat",
"salt": "OUjisBdQ",
"md5": "8148d51998f3fef835a5f3979218c181",
"sha1": "131ae09d045b345efe36a330bf17a450b76f7de3",
"sha256": "94c3a362b5f516d0fb1d4e9dbb632d32d57b8886d5cc7bf0d5cedc99e7d55219"
},
"dob": "1957-04-26 22:07:14",
"registered": "2002-04-29 10:57:34",
"phone": "0556-4348870",
"cell": "0172-5116200",
"id": {
"name": "",
"value": null
},
"picture": {
"large": "https://randomuser.me/api/portraits/men/14.jpg",
"medium": "https://randomuser.me/api/portraits/med/men/14.jpg",
"thumbnail": "https://randomuser.me/api/portraits/thumb/men/14.jpg"
},
"nat": "DE"
}
],
"info": {
"seed": "8fd4afe85884c767",
"results": 1,
"page": 1,
"version": "1.1"
}
}
Refer this example showing my issue.
If you have a sorting issue with indexing and you think it's related.. you could work around the issue by assigning an index:
*ngFor="let user of users; let i = index"
and then reference the direct index value
users[i]
You should make a copy of that array. Editing array elements while looping them can lead to unexpected behaviour.
I guess I'm stuck on stupid. I've been at this for the last few hours and can't seen to figure it out. Admittedly, I am new to ng/ionic2.
I am trying to loop through the response from my post request. I am getting a valid(validated online) big, fat JSON object from my own web api. It looks like this:
`"details": [{
"item_ID": "4",
"item_attribute_ID": "JiggyJamband_1_642",
"item_color_bool": "false",
"item_name": "Test Item 4",
"item_price": "18.95",
"item_desc": "4 This is a test of the ajax input",
"item_gender": "Girls"
},
{ ... },
"attributes": {
"JiggyJamband_1_642": [{
"color": "no-color",
"Xs": "80",
"Sm": "0",
"Med": "0",
"Lrg": "0",
"Xl": "0",
"Xxl": "10"
}],
"JiggyJamband_5_5664": [{
"color": "no-color",
"Xs": "0",
"Sm": "0",
"Med": "0",
"Lrg": "0",
"Xl": "0",
"Xxl": "50"
}],
{ ... }`
I am able to access individual "details" and "attributes" like this:
this.itemsDataService.getRemoteData(urlCode)
.subscribe(response => {
this.itemsJson = response;
this.dObj = this.boothItemsJson.details;
//this.aObj = this.boothItemsJson.attributes;
this.aObj = response["attributes"]["JiggyJamband_1_642"];
});
My provider looks like this:
getRemoteData(urlCode): any {
return this.http.post('http://localhost/process-fe-app/_itemJson.php', JSON.stringify(urlCode))
.map(res => res.json()); }
My question: items in details is dynamic and has an item-attribute_ID that is related to at least 1 entry in attributes. Entrys for attributes are dynamic as well - each item can have multiple attributes. The array keys of the individual attributes are the static (sizes and colors) and either have values or they don't. I need to be able to loop over the attributes object (aObj) of arrays and the arrays inside them. I do not need the ngFor or ngIf statements as this data won't be directly displayed per se. The json data is returned just fine but I just need to be able to access it call methods on the based on the data (like putting into storage with the attribute ID as the key "JiggyJamband: color: no-color, xs:50, s:100... etc"
What I've tried: this tutorial https://www.youtube.com/watch?v=0kHJgw6Li_4, and googling ever iteration of the wording for this problem I could think of.
Perhaps this sample iteration will help you get your head around it.
this.itemsDataService.getRemoteData(urlCode)
.subscribe(response => {
for(var k in response){
for(var k2 in response[k]){
console.log([k,k2,response[k][k2]]);
}
}
});
I keep running into some confusing solutions and unclear ways to wrap items that match into a div using backbone.
I am just building a simple example for myself, and would like to nest all models in a collection that have the same attribute team, using a comparator works well in organizing the list, but for the life of me I can't find a clear solution to wrapping each so that I have more control over the list of players inside the team.
There has to be a clear easy solution for a beginner like me. I really just want to keep things as clean and simple as possible. My desired html result looks like below.
<div class="pacers">
<li>Paul</li>
<li>Roy</li>
</div>
<div class="bulls">
<li>Kirk</li>
<li>Taj</li>
</div>
Based on a backbone friendly json array like below.
[
{
"name": "Paul",
"team": "pacers"
},
{
"name": "Kirk",
"team": "bulls"
},
{
"firstname": "George",
"team": "pacers"
},
{
"name": "Taj",
"team": "bulls"
}
]
So using a comparator is awesome I just write this comparator : 'team' and it handles the list order for me, cool, but I dont have much control I would like to wrap the list in a more hierarchical system.
Another approach:
If you are using underscore's templates this could be one way of doing it. You can use underscore's groupBy function to group the list based on teams.
var teams = [
{
"name": "Paul",
"team": "pacers"
},
{
"name": "Kirk",
"team": "bulls"
},
{
"firstname": "George",
"team": "pacers"
},
{
"name": "Taj",
"team": "bulls"
}
];
var groupedList = _.groupBy(list, function(l){
return l.team;
});
console.log(JSON.stringify(groupedList));
This is how it would be grouped.
{
"pacers": [
{
"name": "Paul",
"team": "pacers"
},
{
"firstname": "George",
"team": "pacers"
}
],
"bulls": [
{
"name": "Kirk",
"team": "bulls"
},
{
"name": "Taj",
"team": "bulls"
}
]
}
You can then use for each loop and in template and generate HTML in following way. The groupedList is passed as teams to below template.
<%
_.each(teams, function(team, teamName){
%>
<div class="<%=teamName%>">
<%
_.each(team, function(player){
%>
<li><%=player.name%></li>
<%
});
%>
</div>
<%
});
%>
This would generate the HTML the way you expected.
NOTE:
The code snippets are given considering underscore templating, you might have to make changes based on what you use. Hope it helps.
Correct me if I am wrong the problem being described relates more to controlling the contents of each item in relation to it's model as well as how to simply render them in groups.
1) Niranjan has covered grouping out the data into separate lists but remember that this list returned is not a Backbone construct.
2) As per the manual the '_.groupBy' method should be available to you via the collection i.e.:
myCollection.groupBy(etc);
3) I would personally consider mapping the results of the groupBy back into models and pass each and every model into a separate view and render them from within the main list view.
var CollectionView = Backbone.View.extend({
initialize : function () {
// Note: I am pretending that you have a real collection.
this.collection.fetch().then(
this.addAll(true);
);
}
addOne : function (model) {
// call .render individual template items here for each model.
var view = new ItemView(model);
this.$el.append(view.render();
},
addAll : function (groupOpts) {
var col = this.collection;
if(groupOpts === true) {
// Do grouping (or do it in the model). Maybe put back into new collection?
}
_.each(col, function(model) {
this.addOne(model);
}, this);
},
render : function () {
// Render your template here.
}
});
var ItemView = Backbone.View.extend({
render : function () {
}
});
Not a complete example but that's the general pattern I would follow when attempting the same thing. Having an individual view/model for each item, in my opinion, gives you more control.
This could be handled in a pretty crazy view template (depends on your template language)... or you could use a simpler template/view and just make some more crazy collection queries (first using a pluck to get the team, de-dupping that array, then running some where's for each of the teams... but you can see how this gets crazy)
I'd vote for the view and view template should handle this... what are you using? Jade? Mustache?
Something like this - logical psuedo code here since I don't know your template language:
var team;
forEach player in players
if(!team) {
set team = player.team
print open holder and then the first row
} (team !== player.team {
set team = player.team
print close of previous holder, then open holder and then the first row of new team
} else {
print just the player row
}
Even so, you can see how this is a bit dirty in and of itself... but what you are describing is a view/presentation concern, and you can do it here with no new additional loops and maps and wheres (like you'd have to do if you did it in the data layer before calling the views)