Javascript for loop in shows undefined - javascript

MY JSON is:
[
{
"id": "5d7d855c-7301-4b2f-9676-3cb758316b4c",
"products": [
{
"id": 1,
"price": 699.0,
"quantity": 2,
"color": "silver",
"size": "128GB"
}
],
"contact": {
"name": "5423654",
"surname": "gdfsgsdf",
"address": "gfdsg",
"phone": "53454353",
"city": "5234532",
"country": "gfdsgfds"
},
"shippingPrice": 0.0,
"discount": null,
"totalPrice": 1398.0
}
]
I am trying to loop in it with for loop in
class Orders {
_orders;
constructor() {
this.init().then(() => this.renderOrders());
}
async init() {
this._orders = await this.getOrders();
}
GET(url) {
try {
return axios.get(url)
} catch (e) {
return e;
}
}
getOrders() {
return new Promise(resolve => {
this.GET('http://localhost:8080/orders/getOrders').then(response => {
resolve(response.data);
})
})
}
renderOrders() {
const template = document.getElementById("orders__template");
const container = document.getElementById("orders");
container.innerHTML = "";
console.log(typeof this._orders);
for (let key in this._orders) {
if (this._orders.hasOwnProperty(key)) {
for (let productKey in this._orders[key].products) {
if (this._orders[key].products.hasOwnProperty(productKey)) {
console.log(this._orders[key].products[productKey].id); //getting the id
}
}
for (let discountKey in this._orders[key].discount) {
if (this._orders[key].discount.hasOwnProperty(discountKey)) {
console.log(this._orders[key].discount[discountKey].id); //undefined(even when it's not null, why?
}
}
for (let contactKey in this._orders[key].contact) {
if (this._orders[key].contact.hasOwnProperty(contactKey)) {
console.log(this._orders[key].contact[contactKey].name); //undefined too
}
}
}
}
}
document.addEventListener("DOMContentLoaded", () => {
new Orders();
});
However, i am getting only at first for loop result, other discount, or contact are undefined.
i tried with other dummy data, i am getting the same results, so, what is the problem? However, i have other examples where it do work, the same structure, whats wrong?

in the orders object, property discount and contact are not arrays so you don't need to use for loop:
for (let key in order) {
if (order.hasOwnProperty(key)) {
for (let productKey in order[key].products) {
if (order[key].products.hasOwnProperty(productKey)) {
console.log(order[key].products[productKey].id); //getting the id
}
}
if (order[key].discount) {
console.log(order[key].discount.id);
}
if (order[key].contact) {
console.log(order[key].contact.name);
}
}
}

Related

Sequelize returning null values from database (API problem)

I seem to have a problem with Sequelize .
The thing is i have set an SQL database , when i try to reach it via sequelize (node) it just returns nulled values
[
{
"id": null
},
{
"id": null
},
{
"id": null
},
{
"id": null
},
{
"id": null
},
{
"id": null
},
{
"id": null
},
{
"id": null
},
{
"id": null
},
{
"id": null
},
{
"id": null
}
]
This is my service,
When i create an object inside the findUsers function and return as if it is real data , it just works
const User = require('../models/User');
const addUser = async (user) => {
try {
await User.create(user)
} catch (e) {
console.log(e);
}
}
const findUsers = async () => {
try {
//return await User.findAll({});
const u = User.findAll();
/*u = {
nom : "lozo",
}*/
return u;
} catch (e) {
console.log(e)
}
}
module.exports = {addUser,findUsers}

Response object data using as array

I have to write map function based on response data but response data is not an array
example response
{
"data": {
"e680c823-895b-46f0-b0a0-5f8c7ce57cb2": {
"id": 98218,
......
},
"e24ed385-0b86-422e-a4cc-69064846e13b": {
"id": 98217,
.......
},
"c1cc583b-a2be-412b-a286-436563984685": {
"id": 118868,
.....
},
}
var posts = data.map(function (item) {
return item.id;
});
I have to achieve like this console
console.log( posts[1].id ) //98217
map over the Object.values and return the nested object.
const data = {
data: {
"e680c823-895b-46f0-b0a0-5f8c7ce57cb2": {
"id": 98218
},
"e24ed385-0b86-422e-a4cc-69064846e13b": {
"id": 98217
},
"c1cc583b-a2be-412b-a286-436563984685": {
"id": 118868
}
}
};
const posts = Object.values(data.data).map(obj => obj);
console.log(posts[1].id);
Object.values() returns an array of Object values. You can loop over them to get your desired result.
let respData = {
"data": {
"e680c823-895b-46f0-b0a0-5f8c7ce57cb2": {
"id": 98218
},
"e24ed385-0b86-422e-a4cc-69064846e13b": {
"id": 98217
},
"c1cc583b-a2be-412b-a286-436563984685": {
"id": 118868
}
}
}
var posts = Object.values(respData['data']).map(function (item) {
return item;
});
console.log(posts[0].id) //98218

Skip JSON.map() for the subsequent elements

DEMO
(Please check the browser console for output)
I have a JSON customerItemResponse in a format
{
"totalResults": someNumber,
"results": [
{
"totalItem": 406,
"customerId": "10000"
},
{
"totalItem": 468,
"customerId": "10001"
},
{
"totalItem": 20,
"customerId": "10002"
},
...
Then I have another JSON customerInfo:
{
"totalResults": someNumber,
"results": [
{
"customerId": "10000",
"region": "4",
"area": "42",
},
{
"customerId": "10001",
"region": "4",
"area": "43",
},
{
"customerId": "10002",
"region": "5",
"area": "52",
},
Now I have to create a JSON in a format
[
{
region:'4'
regionDetails:[
{
area:'42'
customerDetails:[
{
customerId:'10000'
totalItem:406
},
{
customerId:'10005'
totalItem:301
},
]
},
{
area:'11'
customerDetails:[
{
customerId:'10010'
totalItem:11
},
{
customerId:'10021'
totalItem:105
},
]
},
]
},
{
region:'5'
regionDetails:[
{
area:'52'
customerDetails:[
{
customerId:'10002'
totalItem:52
},
{
customerId:'10027'
totalItem:310
},
]
},
{
area:'41'
customerDetails:[
{
customerId:'10017'
totalItem:109
},
{
customerId:'10041'
totalItem:450
},
]
},
]
}
]
This is the logic I have written:
customerData=<CustomerDataInterface[]>[]
mapJson() {
this.customerItemResponse.map((res, index) => {
this.customerInfo.find((obj) => {
if (obj.customerId == res.customerId) {
this.customerData.length
? this.customerData.map((data, index1) => {
if (data.region == obj.region) {
data.regionDetails.length
? data.regionDetails.map((regDetails, index2) => {
if (regDetails.area == obj.area) {
regDetails.dealerDetails.push({
customerId: obj.customerId,
totalItem: res.totalItem,
});
return;
}
if (index2 == data.regionDetails.length - 1) {
data.regionDetails.push({ area: obj.area, dealerDetails: [] });
}
})
: data.regionDetails.push({ area: obj.area, dealerDetails: [] });
return;
}
if (index1 == this.customerData.length - 1) {
this.customerData.push({ region: obj.region, regionDetails: [] });
}
})
: this.customerData.push({ region: obj.region, regionDetails: [] });
}
});
});
console.log(this.customerData);
}
Now the output of the console has several region repeated. And suppose if I have 6 unique region but the this.customerData.length is 31.
I think return; is not working as expected. And is not skipping the subsequent element.
here is an efficient way to resolving the issue using js Maps. We can build maps with info about corresponding region and then areas. and after the data is built into maps - convert it back to simple js structures, such as object and arrays
mapJson() {
const customerToTotalMap = new Map(this.customerItemResponse.map(({customerId, totalItem}) => [customerId, totalItem]));
const regionsMap = new Map();
for(let {customerId, region, area} of this.customerInfo) {
let regionAreas;
if(regionsMap.has(region)) {
regionAreas = regionsMap.get(region);
} else {
regionAreas = new Map();
regionsMap.set(region, regionAreas);
}
let areaInfo;
if(regionAreas.has(area)) {
areaInfo = regionAreas.get(area);
} else {
areaInfo = [];
regionAreas.set(area, areaInfo);
}
areaInfo.push({customerId, totalItem: customerToTotalMap.get(customerId)});
}
this.customerData = [...regionsMap.entries()].map(([region, areas]) => ({
region,
regionDetails: [...areas.entries()].map(([area, customerDetails]) => ({
area,
customerDetails
}))
}))
console.log(this.customerData);
}
This is similar to #Andrei's answer. It creates an object literal as mapper. Also, it uses mapping between the region and area when they are created. So, finally you can just get the values of the regionMapper object without going through the mapper objects again
const customerItemResponse=[{customerId:10000,totalItem:77},{customerId:10001,totalItem:37},{customerId:10002,totalItem:295},{customerId:10003,totalItem:458},{customerId:10004,totalItem:248},{customerId:10005,totalItem:35},{customerId:10006,totalItem:280},{customerId:10007,totalItem:147},{customerId:10008,totalItem:439},{customerId:10009,totalItem:401},{customerId:10010,totalItem:489},{customerId:10011,totalItem:414},{customerId:10012,totalItem:287},{customerId:10013,totalItem:391},{customerId:10014,totalItem:125},{customerId:10015,totalItem:207},{customerId:10016,totalItem:197},{customerId:10017,totalItem:151},{customerId:10018,totalItem:225},{customerId:10019,totalItem:333},{customerId:10020,totalItem:361},{customerId:10021,totalItem:225},{customerId:10022,totalItem:242},{customerId:10023,totalItem:150},{customerId:10024,totalItem:52},{customerId:10025,totalItem:475},{customerId:10026,totalItem:494},{customerId:10027,totalItem:30},{customerId:10028,totalItem:189},{customerId:10029,totalItem:112},{customerId:10030,totalItem:482},{customerId:10031,totalItem:283},{customerId:10032,totalItem:159},{customerId:10033,totalItem:440},{customerId:10034,totalItem:461},{customerId:10035,totalItem:76},{customerId:10036,totalItem:84},{customerId:10037,totalItem:392},{customerId:10038,totalItem:296},{customerId:10039,totalItem:293},{customerId:10040,totalItem:135},{customerId:10041,totalItem:348},{customerId:10042,totalItem:338},{customerId:10043,totalItem:444},{customerId:10044,totalItem:15},{customerId:10045,totalItem:32},{customerId:10046,totalItem:67},{customerId:10047,totalItem:277},{customerId:10048,totalItem:65},{customerId:10049,totalItem:95},{customerId:10050,totalItem:290}],
customerInfo=[{customerId:10000,region:"3",area:"32"},{customerId:10001,region:"2",area:"22"},{customerId:10002,region:"2",area:"25"},{customerId:10003,region:"3",area:"31"},{customerId:10004,region:"2",area:"25"},{customerId:10005,region:"1",area:"11"},{customerId:10006,region:"1",area:"14"},{customerId:10007,region:"5",area:"55"},{customerId:10008,region:"5",area:"51"},{customerId:10009,region:"4",area:"45"},{customerId:10010,region:"1",area:"14"},{customerId:10011,region:"1",area:"12"},{customerId:10012,region:"3",area:"33"},{customerId:10013,region:"2",area:"25"},{customerId:10014,region:"4",area:"41"},{customerId:10015,region:"3",area:"32"},{customerId:10016,region:"5",area:"55"},{customerId:10017,region:"2",area:"23"},{customerId:10018,region:"3",area:"33"},{customerId:10019,region:"5",area:"51"},{customerId:10020,region:"4",area:"42"},{customerId:10021,region:"1",area:"12"},{customerId:10022,region:"1",area:"14"},{customerId:10023,region:"1",area:"14"},{customerId:10024,region:"1",area:"13"},{customerId:10025,region:"4",area:"45"},{customerId:10026,region:"3",area:"34"},{customerId:10027,region:"2",area:"24"},{customerId:10028,region:"4",area:"45"},{customerId:10029,region:"2",area:"22"},{customerId:10030,region:"2",area:"22"},{customerId:10031,region:"2",area:"21"},{customerId:10032,region:"3",area:"33"},{customerId:10033,region:"1",area:"11"},{customerId:10034,region:"3",area:"33"},{customerId:10035,region:"3",area:"32"},{customerId:10036,region:"2",area:"22"},{customerId:10037,region:"4",area:"41"},{customerId:10038,region:"3",area:"31"},{customerId:10039,region:"5",area:"51"},{customerId:10040,region:"2",area:"23"},{customerId:10041,region:"4",area:"45"},{customerId:10042,region:"1",area:"14"},{customerId:10043,region:"5",area:"54"},{customerId:10044,region:"3",area:"34"},{customerId:10045,region:"5",area:"51"},{customerId:10046,region:"4",area:"42"},{customerId:10047,region:"5",area:"53"},{customerId:10048,region:"1",area:"11"},{customerId:10049,region:"3",area:"35"},{customerId:10050,region:"5",area:"51"}];
const customerItemMapper = {}
for (const c of customerItemResponse)
customerItemMapper[c.customerId] = c.totalItem
const regionMapper = {},
areaMapper = {};
for (const { customerId, region, area } of customerInfo) {
let regionKey = `Region_${region}`,
areaKey = `Area_${area}`,
totalItem = customerItemMapper[customerId];
if (!(regionKey in regionMapper))
regionMapper[regionKey] = { region, regionDetails: [] }
if (!(areaKey in areaMapper)) {
const o = { area, customerDetails: [] }
areaMapper[areaKey] = o;
regionMapper[regionKey].regionDetails.push(o) // area-region relation
}
areaMapper[areaKey].customerDetails.push({ customerId, totalItem })
}
console.log(Object.values(regionMapper))

recursion with Promises

I have a collection in MongoDB like this
[
{
"classId": "1",
"name": "Input",
"definition": [
{
"property": [
{
"classId": "12",
"name": "One"
},
{
"classId": "8",
"name": "Comment"
}
]
}
]
},
{
"classId": "8",
"name": "CommentDetail",
"definition": [
{
"property": [
{
"classId": "10",
"name": "user"
},
{
"classId": "10",
"name": "message"
}
]
}
]
},
{
"classId": "10",
"name": "String",
"definition": []
},
{
"classId": "12",
"name": "Int",
"definition": []
}
]
Based on db above, I have a model to display
data = {
name:'',
template: ''
}
With classId=1, the expectation result is
{
"Name": "Input",
"temlate": "{['One': 'Int','Comment': ['user': 'String','message':'String']]}"
}
I try to using recursive promise to implement it. When property[] is empty, the result will be return.
Here is my function:
const getObjectTypeByClassId = (snapshotId, artifactId, objectType) => {
return artifactDetailModel.find({
'snapshotId': snapshotId,
'artifactId': artifactId
})
.then(data => {
let artifact = data[0];
let definition;
let definitionData = {};
return Promise.resolve()
.then(() => {
definition = artifact.data.teamworks.twClass[0].definition[0];
if (!lodash.isUndefined(definition.property)) {
const listOfProperty = definition.property;
for (let property of listOfProperty) {
classId = commonUtil.getArtifactId(property.classRef[0]);
if (!lodash.isUndefined(classId)) {
return getObjectTypeByClassId(snapshotId, classId, objectType);
}
}
} else {
definitionData.nameType = artifact.data.teamworks.twClass[0].elementAttribute.name;
definitionData.classId = artifact.data.teamworks.twClass[0].elementAttribute.id;
definitionData.template = bpmMapping.objectType[artifact.data.teamworks.twClass[0].elementAttribute.name];
return objectTypeModel.create(definitionData)
.then(obj => {
const response = {
name: objectType.name,
isArrayOf: objectType.isArrayOf,
nameType: obj.nameType,
template: obj.template,
}
return response;
})
}
})
})
}
Run with my function, the response is
data: {
Name: Input
temlate: user: String,
}
Please advice me.
I tried it to some extent, but wasn't able to get it right. Plus your expected output is not the valid JSON "temlate": {[]} doesn't make sense.
It has nothing to do with Promise. You have to DFS you db array and created expected output. Here is what I have donup tillll now, you can think along those lines. But this is far from the solution.
let mainArray = [
{
"classId": "1",
"name": "Input",
"definition": [
{
"property": [
{
"classId": "12",
"name": "One"
},
{
"classId": "8",
"name": "Comment"
}
]
}
]
},
{
"classId": "8",
"name": "CommentDetail",
"definition": [
{
"property": [
{
"classId": "10",
"name": "user"
},
{
"classId": "10",
"name": "message"
}
]
}
]
},
{
"classId": "10",
"name": "String",
"definition": []
},
{
"classId": "12",
"name": "Int",
"definition": []
}
]
function dfs(root, createdRoot, fn, level) {
fn(root,createdRoot, level);
if(root.definition)/*if definition exists => keep traversing*/
root.definition[0].property.forEach(function (child) {
createdRoot.template = createdRoot.template || [];
let tempObj = {};
let lookupObj = lookupByClassId(child.classId);
tempObj[child.name] = lookupObj.name;
createdRoot.template.push(tempObj);
dfs(child,tempObj, fn, level + 1);
});
else /*if definition doesn't exist, look into the array*/
{
createdRoot.template = lookupByClassId(root.classId);
}
}
function lookupByClassId(classId){
for(let i=0;i<mainArray.length;++i){
let element =mainArray[i]
if(element.classId == classId)
return element;
}
}
let root = lookupByClassId(1);
createdRoot ={};
function func1(root, createdRoot, level) {
createdRoot.name = root.name;
console.log(root.classId);
}
dfs(root, createdRoot, func1, 0);
here is the solution from a guy on the internet. it works well. Thanks, #Cuong Quach
var MongoClient = require('mongodb').MongoClient;
var database = 'testdequy';
var collection = 'classes';
MongoClient.connect("mongodb://localhost:27017/" + database, function (err, db) {
findDetails("1").then((r) => {
console.log("r>>>", r);
})
function findDetails(classId) {
var results = { Name: "", Template: "" };
var template = {};
return new Promise((main_resolve, reject) => {
process(template, "" , classId)
var works = 0;
function process(parent, childKey, objectId) {
return new Promise((resolve, reject) => {
db.collection(collection).find({ classId: objectId })
.toArray((err, docs) => {
if (results.Name == "") {
results.Name = docs[0].name;
}
let objectItem;
if (childKey == "")
objectItem = parent;
else
objectItem = parent[childKey];
console.log("\ndocs", docs[0], objectId, objectItem)
if (docs[0].definition.length == 0 || docs[0].definition[0].property == undefined) {
let name = docs[0].name;
parent[childKey] = name;
console.log("\nNo child", docs[0],parent, objectItem, docs[0].name)
resolve(0);
} else {
docs[0].definition[0].property.forEach((item) => {
works++;
//console.log("item", item)
let id = item.classId;
let name = item.name;
objectItem[name] = {};
process(objectItem, name, id).then((len)=>{
works--;
if(len == 0 && works == 0) main_resolve(template);
})
})
resolve(docs[0].definition[0].property.length)
}
})
})
}
})
}
});

Delete certain parts of json array

I'd like to create a new JSON array based on certain values.
Sample JSON:
var array =
{
"entries": {
"houses": [
{
"category": {
"category_id":"1",
"category_foo":"bar",
},
"important": {
"important_foo":"bar",
"dontforget":"me",
}
},
{
"category": {
"category_id":"1",
"category_foo":"bar",
},
"important": {
"important_foo":"bar",
"dontforget":"me",
}
},
"category": {
"category_id":"2",
"category_foo":"bar",
},
"important": {
"important_foo":"bar",
"dontforget":"me",
}
}
]
}
}
Now I need a way to search through this array and create a new array with all houses that have a category with category_id=1. Of course it should keep all the rest of the infos like important.
The new array should look like:
{
"entries": {
"houses": [
{
"category": {
"category_id":"1",
"category_foo":"bar",
},
"important": {
"important_foo":"bar",
"dontforget":"me",
}
},
{
"category": {
"category_id":"1",
"category_foo":"bar",
},
"important": {
"important_foo":"bar",
"dontforget":"me",
}
}
]
}
}
Any help is appreciated!
You can use Array.filter to do this:
var filteredResults = array.entries.houses.filter(function(house) {
return house.category && house.category_id == 1;
});
This code works.
var houses = array.entries.houses;
var newHouses = [];
for (var i = 0; i < houses.length; i++)
{
if (houses[i].category.category_id == "1") {
newHouses.push(houses[i]);
}
}
Check this out: https://jsfiddle.net/2u13phw3/

Categories

Resources