trying to convetr json array to multiple json objects in nodejs - arrays

trying to convetr json array to multiple json objects in nodejs looking for help here is my code have tried loops to achieve that but failed just want to send the data as multiple objects not array
router.get('/frontpage-mobile', function (req, res, next) {
qryFilter = { "Product_Group": 'SIMPLE' };
// if we have a cart, pass it - otherwise, pass an empty object
var successMsg = req.flash('success')[0];
var errorMsg = req.flash('error')[0];
Product.find(qryFilter, function (err, product) {
// console.log("Product: " + JSON.stringify(product));
var pro=JSON.stringify(product)
if (err || product === 'undefined' || product == null) {
// replace with err handling
var errorMsg = req.flash('error', 'unable to find product');
res.send(errorMsg);
}
if (!product) {
req.flash('error', 'Product is not found.');
res.send('error', 'Product is not found.');
}
for(i=0;i<pro.length;i++)
res.send(pro[i]);
});
});

// Dummy Mongodb Result Array
var db_result = [{_id:1,name:"Cake_1"},{_id:2,name:"Cake_2"},{_id:3,name:"Cake_3"}]
// define data variable
var data = { total : 0, dataObj : {} } // default total = 0, = {}
var dataObj = {}
// convert array to obj
// { key1 : obj1, key2 : obj2, key3 : obj3, ... }
for(var i=0; i < db_result.length;i++){
let key = "key"+i;
dataObj[key] = db_result[i];
}
// assign data to variable
data.total = db_result.length;
data.dataObj = dataObj
// rend back to client
res.send(data);
// Result
{
"total":3,
"dataObj":{
"key0":{"_id":1,"name":"Cake_1"},
"key1":{"_id":2,"name":"Cake_2"},
"key2":{"_id":3,"name":"Cake_3"}
}
}

Related

How to return this local variable in nested functions and "globalize" it?

I am trying to catch some values from a file and put them in an array.
After battling up with conversions and values, I reach my "final" data to return which in my case is arrayFile.I understand that I have nested some functions and now I couldn't return my data properly and globally in the first part of the code, because it displays/returned undefined.
In a few words,how I can retutn this variable specifically or in another variable? Because the console.log works, however just in that block. How could I end my 1st FOR loop and keep the data (arrayFile) global so for being used in other stuff? Any help wuold be precious. Hoping I'm asking questions the right way, thanks for your patience.
const directoryPath = path.join(__dirname, './sample');
//passing directoryPath and callback function
fs.readdir(directoryPath, function (err, files) {
//handling error
if (err) {
return console.log('Unable to scan directory: ' + err);
}
//listing all files using forEach
files.forEach(function (file) {
arrayNomi.push(file);
});
for(i=0;i<arrayNomi.length;i++){
leggiFile(arrayNomi[i],arrayDati)
}
});
function leggiFile(nomeFile,arrayFile){
const xmlFile = fs.readFile(nomeFile,{encoding:'utf8', flag:'r'},
function(err, data) {
if(err)
console.log(err);
else
convert.parseString(data, (err, result) => {
if(err) {
throw err;
}
// `result` is a JavaScript object
// convert it to a JSON string
//const json = JSON.stringify(result, null, 4);
//console.log(json)
// log JSON string
//console.log(json);
// method to collect string values
const collectAllValues = (arr, res = []) => {
// append result "res" with any "string" elt in array "arr"
const r = [
...res,
...(
arr?.filter(
elt => typeof elt !== 'object'
) ?? []
)
];
// filter out "arr" elements that are "objects"
const nx = arr?.filter(
elt => typeof elt === 'object'
) ?? [];
// if "objects" exist in "arr" elements-list
// use ".reduce()" to iterate over the filtered "arr"
// then, for each object, use ".reduce()" to
// iterate over values that are arrays and make
// recursive call to this method & return the value
if (nx && nx.length) {
return (
nx.reduce(
(acc, ob) => ([
...acc,
Object.values(ob)
.filter(v => v && Array.isArray(v))
.reduce((ac2, ar) => ([...ac2, ...collectAllValues(ar)]), acc)
.flat()
]),
r
)
);
} else return r;
// if no "objects" exist, simply return earlier
// result "r"
};
console.log(
'collect all values:\n',
Object.values(result["p:FatturaElettronica"])
.filter(v => v && Array.isArray(v))
.reduce((acc, ar) => ([...acc, ...collectAllValues(ar)]), [])
.flat()
);
var jsonDatiTabella = {};
var dati = [];
jsonDatiTabella.dati = dati;
var tipoDocumento= result["p:FatturaElettronica"].FatturaElettronicaBody[0].DatiGenerali[0].DatiGeneraliDocumento[0].TipoDocumento[0];
var dataDocumento= result["p:FatturaElettronica"].FatturaElettronicaBody[0].DatiGenerali[0].DatiGeneraliDocumento[0].Data[0];
var importo = result["p:FatturaElettronica"].FatturaElettronicaBody[0].DatiGenerali[0].DatiGeneraliDocumento[0].ImportoTotaleDocumento[0];
var prestatore= result["p:FatturaElettronica"].FatturaElettronicaHeader[0].CedentePrestatore[0].DatiAnagrafici[0].Anagrafica[0].Denominazione[0];
var committente= result["p:FatturaElettronica"].FatturaElettronicaHeader[0].CessionarioCommittente[0].DatiAnagrafici[0].Anagrafica[0].Nome[0];
var tempDati = {
"TipoDoc": tipoDocumento,
"DataDoc": dataDocumento,
"Importo":importo,
"CedentePrestatore" :prestatore,
"CessionarioCommittente":committente
}
jsonDatiTabella.dati.push(tempDati);
console.log(jsonDatiTabella);
arrayFile.push(tempDati.TipoDoc,tempDati.DataDoc,tempDati.Importo,tempDati.CedentePrestatore,tempDati.CessionarioCommittente)
console.log("arrayFile:" + arrayFile)
});
});
}

contentVersion (image/png) created is empty

//lightning controller- Here I am capturing the signature in a hidden canvas and extracting the base64 data from it , and sending it to the server side apex
var tCtx = document.getElementById('textCanvas').getContext('2d'),
imageElem = document.getElementById('Signimage');
tCtx.canvas.width = 720;
tCtx.canvas.height= 100;
tCtx.font = "italic 30px monospace";
var theSignature = n; // name of person - the text that is to be converted to an img
tCtx.fillText(theSignature,10, 50);
imageElem.src = tCtx.canvas.toDataURL();
var base64Canvas = tCtx.canvas.toDataURL().split(';base64,')[1];
component.set('{!v.storeApplicantSign}',base64Canvas);
//lightning helper
uploadonSubmit: function(component,event,helper) {
// call the apex method 'saveChunk'
var action = component.get("c.saveChunk");
action.setParams({
parentId: component.get("v.recordId"),
base64Data: component.get("v.storeApplicantSign"), // contains the base64 data
});
// set call back
action.setCallback(this, function(response) {
// store the response / Attachment Id
var result = response.getReturnValue();
var state = response.getState();
if (state === "SUCCESS") {
alert("Success");
// this.showtheToast();
} else if (state === "INCOMPLETE") {
alert("From server: " + response.getReturnValue());
} else if (state === "ERROR") {
var errors = response.getError();
if (errors) {
if (errors[0] && errors[0].message) {
console.log("Error message: " + errors[0].message);
}
} else {
console.log("Unknown error");
}
}
});
// enqueue the action
$A.enqueueAction(action);
},
// apex class
//Here decoding the data from the lightning and creating content version
#AuraEnabled
public static Id saveChunk(Id parentId,String base64Data) {
String fileId = saveTheFile(parentId,base64Data,'Signature.png');
return Id.valueOf(fileId);
}
public static Id saveTheFile(Id parentId,String base64Data,String fileName) {
base64Data = EncodingUtil.urlDecode(base64Data,'UTF-8');
ContentVersion contentVersion = new ContentVersion(
versionData = EncodingUtil.base64Decode(base64Data),
title = fileName,
pathOnClient = 'Signature'+'.'+'png',
ContentLocation='S',
FirstPublishLocationId = parentId);
system.debug('contentversion data=> '+contentVersion+'version data ----> '+contentVersion.VersionData);
insert contentVersion;
return contentVersion.Id;
}
// File is being created but it's empty that is image is not there / can't be opened as img
The issue was in apex side :
just removed the line :
`base64Data = EncodingUtil.urlDecode(base64Data,'UTF-8'); // this wasn't required
removing the above line solved it .

React state array object changes without setState

I have an array which is a state of the React component. This array is a checklist.
var units1 = this.state.units;
when I update units1, this.state.units changes without the this.setState({ units: units1 })
I use this.setState({ a: 2 }); just to see if the array was updated without this.setState({ units: units2 });
this.state.units gets its value from props so if the state changes the props also changes.
handleItemChange(e) {
var units1 = this.state.units.slice();
var unit_name = parseInt(e.target.attributes.getNamedItem('data-unit_name').value);
var new_unit;
if (!e.target.checked && this.state.units && this.state.units.length > 0) {
this.state.units.map((unit) => {
if (unit_name == unit.codpacunidad) {
if (unit.topics && unit.topics.length > 0) {
unit.topics.map((topic) => {
if (topic.codpacunidadtema == e.target.name) {
new_unit = unit;
var index = units1.indexOf(unit);
//units1.splice(index, 1);
units1 = update(units1, {$splice: [[index, 1]]})
var topics1 = unit.topics.slice();
index = topics1.indexOf(topic);
//topics1.splice(index, 1);
topics1 = update(topics1, {$splice: [[index, 1]]})
new_unit.topics = topics1;
}
});
}
}
});
} else {
var found_unit = false;
var name = parseInt(e.target.name);
var order = parseInt(e.target.attributes.getNamedItem('data-order').value);
var unit_order = parseInt(e.target.attributes.getNamedItem('data-unit_order').value);
if (this.state.units && this.state.units.length > 0) {
this.state.units.map((unit) => {
if (unit.codpacunidad == unit_name) {
found_unit = true;
new_unit = unit;
var index = units1.indexOf(unit);
units1.splice(index, 1);
var new_topic = {
codpacunidadtema: name,
orden: order
};
var topics2 = new_unit.topics;
new_unit.topics = update(topics2, { $push: [new_topic]});
}
});
}
if (found_unit == false) {
new_unit = {
codpacunidad: unit_name,
orden: unit_order,
topics: [{codpacunidadtema: name, orden: order }]
};
}
}
// var units2 = update(units1, { $push: [new_unit]});
// this.setState({ units: units2.sort(function(a, b) {
// return parseInt(a.orden) - parseInt(b.orden);
// })
// });
this.setState({ a: 2 }); //just to test if the array gets updated without this.setStaet({ units: units2 })
}
Anybody knows why this is happening?
As #Alexander van Oostenrijk said to make deep copy of array.
Because array are passed by reference which mean memory address of the array is passed not the value of array.
var units1 = this.state.units.slice();
Now units1 has the reference address of that array any change made to units1 or this.state.units.slice() will change value of both.As basically they are using address and if one change the value at address then both will read changed value.Hope you understand
To create deep copy you can create new object like
var units1 = Object.assign([],this.state.units)
This will create new object with data of this.state.units
extras I think you do not need .slice().

combine two array as key value pair

I have two array as follows
var field_array=["booktitle","bookid","bookauthor"];
var data_array=["testtitle","testid","testauthor"];
I want to combine these two array and covert it to the following format
var data={
"booktitle":"testtitle",
"bookid":"testid",
"bookauthor":"testauthor"
}
I want to insert this data to database using nodejs
var lastquery= connection.query('INSERT INTO book_tbl SET ?',data, function (error, results, fields) {
if (error) {
res.redirect('/list');
}else{
res.redirect('/list');
}
});
Please help me to solve this.
var field_array = ["booktitle", "bookid", "bookauthor"];
var data_array = ["testtitle", "testid", "testauthor"];
var finalObj = {};
field_array.forEach(function (eachItem, i) {
finalObj[eachItem] = data_array[i];
});
console.log(finalObj); //finalObj contains ur data
You also can use reduce() in a similar way:
var field_array=["booktitle","bookid","bookauthor"];
var data_array=["testtitle","testid","testauthor"];
var result = field_array.reduce((acc, item, i) => {
acc[item] = data_array[i];
return acc;
}, {});
console.log(result);
Here I explaned my code line by line..Hope it will help
var field_array = ["booktitle", "bookid", "bookauthor"];
var data_array = ["testtitle", "testid", "testauthor"];
//Convert above two array into JSON Obj
var jsondata = {};
field_array.forEach(function (eachItem, i) {
jsondata[eachItem] = data_array[i];
});
//End
//Store Jsondata into an array according to Database column structure
var values = [];
for (var i = 0; i < jsondata.length; i++)
values.push([jsondata[i].booktitle, jsondata[i].bookid, jsondata[i].bookauthor]);
//END
//Bulk insert using nested array [ [a,b],[c,d] ] will be flattened to (a,b),(c,d)
connection.query('INSERT INTO book_tbl (booktitle, bookid, bookauthor) VALUES ?', [values], function(err, result) {
if (err) {
res.send('Error');
}
else {
res.send('Success');
}
//END

AngularJS promise through tow loops

Have some trouble with Angular promise between two loops... First loop walk through an array of value, and for each value, make a PouchDB Query to retrieve some datas. Finally, would like to return to controller a JSON Object that would look like :
{
items: [
{
"attribute": "some value"
},
{
"attribute": "some other value"
},
...
],
"a_total": "some_total",
"another_total": "some_other_total"
}
In this object, "items"
Basically, put the code in a function that looks like :
var _stockByAreas = function(){
var deferred = $q.defer();
var data = {}; // Final datas to return to controller
// Get first array to loop into
var storageAreas = storageAreaService.storageAreaList();
var areas = []; // All of area
// Walk across array
angular.forEach(storageAreas, function(zone){
var area = {}; // First object to return
area.id = zone.id;
area.libelle = zone.libelle;
// Then make a PouchDB query to get all datas that involved
MyKitchenDB.query(function(doc, emit){
emit(doc.storage);
}, { key: area.id, include_docs: true }).then(function (result) {
area.sRef = "tabsController.addTo({id: '" + area.id + "'})";
area.nbProduct = 0;
area.totalQuantity = 0;
area.totalValue = 0;
// ... process result
if(result.rows.length > 0){
// Some results, so... let's go
area.sRef = "tabsController.outFrom({id: '" + area.id + "'})";
var rows = result.rows;
// Counter initialization
var total = 0;
var value = 0;
angular.forEach(rows, function(row){
total++;
var stocks = row.doc.stock;
angular.forEach(stocks, function(stock){
var nearOutOfDate = 0;
var nearStockLimit = 0;
quantity += stock.quantity;
value += stock.quantity * stock.price;
// Evalue la date de péremption
var peremptionDate = moment(stock.until);
var currentDate = moment();
if(currentDate.diff(peremptionDate, 'days') <= 1){
nearOutDate += 1;
}
});
area.nbProduct = total;
area.qteTotale = quantity;
area.valeur = value;
if(quantite == 1){
nearLimitOfStock += 1;
}
areas.push(area); // Add result to main array
});
}
}).catch(function (err) {
// Traite les erreurs éventuelles sur la requête
});
/**
* Hey Buddy... what i have to do here ?
**/
data.items = areas;
data.nearLimitOfStock = nearLimitOfStock;
data.nearOutOfDate = nearOutOfDate;
});
deferred.resolve(data);
return deferred.promise;
}
... But, console returns that "areas" is not defined, and other value too...
I think i don't really understand how promises runs...
Someone is abble to explain why i can't get the result that i expect in my case ?
Thx
Your code is too long, I just give you the approach.
Use $q.all() to ensure all your queries are completed. And use deferred.resolve(data) whenever your data for each query is arrived.
var _stockByAreas = function() {
var query = function(zone) {
var queryDef = $q.defer();
// timeout is for query and response simulations
setTimeout(function() {
// ...
queryDef.resolve( {data: 'MeTe-30'} );
}, 1000);
return queryDef.promise;
}
var promises = [];
angular.forEach(storageAreas, function(zone) {
// ...
promises.push( query(zone) );
});
return $q.all(promises);
}
_stockByAreas().then(function(res) {
// res[0] resolved data by query function for storageAreas[0]
// res[1] resolved data by query function for storageAreas[1]
// ...
});

Resources