Print JSON array in expected format - arrays

This is the code to get the details from my table.
function listshops(callback)
{
var array=[3,4];/*shopId*/
async.each(array,function(dat,callback){
async.parallel([
function(callback){
client.connection.query('select * from shop where shopId=?',dat,function(err,data1){
callback(null,data1);
});
},
function (callback) {
client.connection.query('select * from image where shopId=?',dat,function(err,data2){
callback(null,data2);
});
}
],
function(err,data)
{
var result = data.reduce(function(prev, curr) { /*merging the array*/
return prev.concat(curr);
});
console.log(result);
});
});
}
I got an output like this:: http://i.stack.imgur.com/NVUAu.png
i want to print my result in the below format:
{
"shops": [
{
"shopId": "3",
"shopName": "1",
"address": "abc",
"contactNumber":"1234"
"images": [
{
"imageId": "1",
"shopId": "3",
"imageUrl": "aaa",
},
{
"imageId": "2",
"shopId": "3",
"imageUrl": "bbb",
},
]
},
{
"shopId": "4",
"shopName": "2",
"address": "bbb",
"contactNumber":"1234"
"images": [
{
"imageId": "3",
"shopId": "4",
"imageUrl": "ccc",
},
{
"imageId": "4",
"shopId": "4",
"imageUrl": "ddd",
},
]
},
]
I got the values but some confusions in fetching the values.

You have two nested async tasks here, parallel and each.
Parallel takes care of getting the shop information and the images for one shop and calls the final callback with a two element array that has the results for your tasks.
This is your final callback for parallel:
function(err,data)
{
var result = data.reduce(function(prev, curr) { /*merging the array*/
return prev.concat(curr);
});
console.log(result);
});
data should be a two element array, where element 0 is the shop, and element 1 are the images. You just concatenate these together. If you want your images in the desired format, you should do data[0].images = data[1] to add the images key to your shop.
That so far is for one shop. Then there is the outer each loop. You are currently not giving this a final callback and not doing anything with the result.
Something like this:
function listshops(callback)
{
var array=[3,4];/*shopId*/
async.each(array,function(dat,eachCallback){
async.parallel([
function(parallelCallback){
client.connection.query('select * from shop where shopId=?',dat,function(err,data1){
parallelCallback(null,data1);
});
},
function (parallelCallback) {
client.connection.query('select * from image where shopId=?',dat,function(err,data2){
parallelCallback(null,data2);
});
}
],
// this is the final callback for parallel
function(err,parallelResult)
{
// construct one shop
var shop = parallelResult[0];
shop.image = parallelResult[1];
// pass the shop info back as a result to each
eachCallBack(shop);
});
},
// this is the final callback for each
function(err, eachResult) {
// eachResult is an array with the shops returned from parallel callback
var result = {
shops: eachResult
}
return result
}
);
}
I couldn't test this, so don't consider it an exact solution, but an explanation. I renamed your variables for better understandability, you don't have to do that in your code. The key thing to keep in mind is that you have two nested tasks here, like a nested loop and you also have to deal with the results on two levels.

Related

NodeJS - how to create a JSON file with an array inside in a specified format?

I would like to achieve this JSON structure:
{
"people": [
{
"name": "Peter",
"surname": "Green"
},
{
"name": "Jessica",
"surname": "Morgan"
},
...
}
I am trying to do it like this:
People({}).sort('-createdAt').exec(function(err, people) {
if(err) throw err;
console.log(people);
let data = {}
data['people'] = [];
data.push(people);
res.json(data);
});
When I look at the generated JSON structure, it is in this format:
{
"people": [
[
{
"name": "Peter",
"surname": "Green"
},
...
In the JSON, there are two arrays in the people section. How do I get rid one of the array from there?
Thank you
I assume you're reading from a database, and it looks like it's returning an array of people.
Try not pushing it into a new array?
People({}).sort('-createdAt').exec(function(err, people) {
if(err) throw err;
console.log(people);
let data = {
people: people
};
res.json(data);
});

Updating state of deep object value in React/Redux using immutable.js

I have this pretty deeply nested state array and need to update the Hours field by Employee, Task, and Week. I've attempted numerous ways to do this with Immutable but not having success, any help?
Here is an example of my data :
[{
"Employee": "John Doe",
"Other Data": "test",
"Tasks": [{
"AccessType": "Confidential",
"DueDate": "2016-02-26 23:59:59",
"taskId": "3",
"TaskTitle": "testTitle",
"Weeks": {
"2016-10-10": {
"Hours": "3"
}
}
}]
}, {
"Employee": "Bill Der",
"Other Data": "test",
"Tasks": [{
"AccessType": "Confidential",
"DueDate": "2016-02-26 23:59:59",
"taskId": "3",
"TaskTitle": "testTitle",
"Weeks": {
"2016-10-10": {
"Hours": "3"
}
}
}]
}]
You are missing a bunch of information for me to fully answer this for you, but I can show you how I would do something like this otherwise.
You can take advantage of all the functions immutable js provides you with. So lets say you have an object with the information needed to mutate your immutable object, something like this :
var changeHours = {
"Employee": "John Doe",
"TaskTitle": "testTitle",
"Week": '2016-10-10',
"Hours": "5"
}
And we have a basic state like you have there set up like this :
var myState = Immutable.fromJS([{
"Employee": "John Doe",
"Tasks": [{
"AccessType": "Confidential",
"DueDate": "2016-02-26 23:59:59",
"taskId": "3",
"TaskTitle": "testTitle",
"Weeks": {
"2016-10-10": {
"Hours": "3"
}
}
}]
}]);
Note: I did not add more the the arrays, but we will map over them so they will be taken into account.
You can use immutables map to iterate over and find the items you are looking for, something like this :
var newstate = myState.map((k, v) => {
if (k.get('Employee') === changeHours.Employee) {
return k.get('Tasks').map((k, v) => {
if (k.get('TaskTitle') === changeHours.TaskTitle) {
return k.setIn(['Weeks', changeHours.Week, 'Hours'], changeHours.Hours);
}
return k;
})
return k;
}
return k;
});
To see it in action - http://fiddle.jshell.net/djj6u8xL/63/ . I am iterating over each array level with map and finding the correct node by checking based on our changeHours object and immutables get, then once I am at the right level I just use setIn. You can use updateIn as well, it just depends on your scenario.
In the future, please provide all the information for your question, not just a picture of the data, it will be much easier to help you :) (and not have to type out the data structure manually).
Edit: Update based on comment - http://fiddle.jshell.net/qxbq1nq3/9/
the code :
function newTasks(k) {
return k.get('Tasks').map((k, v) => {
if (k.get('TaskTitle') === changeHours.TaskTitle) {
return k.setIn(['Weeks', changeHours.Week, 'Hours'], changeHours.Hours);
}
return k;
});
}
var newstate = myState.map((k, v) => {
if (k.get('Employee') === changeHours.Employee) {
return k.set('Tasks', newTasks(k));
}
return k;
});

How to merge into array?

Here is my array from db,
[
{
"_id": "58144e6c0c8d7534f4307269",
"doctor_id": "5813221ace684e2b3f5f0a6d",
"prescription": [
{
"_id": "58144e6c0c8d7534f430726a",
"medicine_id": "10011241343"
}
]
I want to merge with only prescription like this
[
{
"_id": "58144e6c0c8d7534f4307269",
"doctor_id": "5813221ace684e2b3f5f0a6d",
"prescription": [
{
"_id": "58144e6c0c8d7534f430726a",
"medicine_id": "10011241343"
},
"prescription": [
{
"_id": "58144e6c0c8d7534f430726a", // it should be autogenerated
"medicine_id": "10011241344"
}
]
How can I do this?
I have tried like this
var arr = data.presription
arr=req.body// which contains only medicine id
and then by
dbModel.user.findById(data._id, function(err, data) {
data.prescription = arr;
data.save(function(err) {
if (err) {
res.status(202).json({
"success": "0",
});
} else {
res.status(200).json({
"success": "1"
});
}
})
});
But it is saving the same. How can I do this?
Note: Even when I do console.log(arr) only the old data is printing.
So data.presription is an array from the start.
data.presription.push( {
"_id": "58144e6c0c8d7534f430726a",
"medicine_id": "10011241344"
});
This is NOT a merge, what you want to do is to append (or push) items into an existing array.

JavaScript (Node.js) - JSON recursion extracting objects to array with order (faltten)

I have a JSON config file as follows:
var conf = [
{
"value": "baz",
"threshold": 20,
"other": 123
},
{
"value": "mo",
"other": 456,
"child": {
"value": "foo",
"other": 789,
"child": {
"value": "larry",
"other": 123
}
}
}
];
I have a requirement to extract each of the objects and persist them together in order if they have child objects. For example, object 1 (baz) is stand alone. Object 2 (mo) will have two child objects. These 3 as a set must be extracted together.
There is no limit to the number of child objects.
Im attempting to persist each object using an array to maintain the order. So the required output would look like:
[[{"value":"baz","threshold":20,"other":123}],
[[{"value":"mo","other":456,"child":{"value":"foo","other":789,"child":{"value":"larry","other":123}}}],
[{"value":"foo","other":789,"child":{"value":"larry","other":123}}],
[{"value":"larry","other":123}]]]
A final requirement is to actually remove the child values from the parents so the output can actually be like:
[
[{"value":"baz","threshold":20,"other":123}],
[
[{"value":"mo","other":456}],
[{"value":"foo","other":789}],
[{"value":"larry","other":123}]
]
]
Ive been hung up on this for hours with little progress. I know I need to create a recursive function, push each node to an array, and then check for child object and repeat.
Heres what I have so far. My thinking is if I can take the array id each task is being pushed to (using a loop id), perhaps I can map that when the function is called again.
Appreciate any guidance.
var execSets = [];
function parser(tasks){
// an ordered array of task execution
for (let eachTask in tasks) {
var taskSet = [];
console.log("====================================");
console.log(tasks[eachTask]);
if(!tasks[eachTask].child && typeof(tasks[eachTask]) === 'object'){
console.log(tasks[eachTask]);
taskSet.push(tasks[eachTask]);
execSets.push(taskSet);
}
if(tasks[eachTask].child){
let childAlias = tasks[eachTask].child;
delete tasks[eachTask].child;
taskSet.push(tasks[eachTask]);
execSets.push(taskSet);
parser(childAlias);
}
}
}
The npm registry is your friend; try 'npm search flat,
There are a few modules that can help flatten a json object. For example https://www.npmjs.com/package/flat
You could do it using recursion. Here is my suggestion:
var conf = [
{
"value": "baz",
"threshold": 20,
"other": 123
},
{
"value": "mo",
"other": 456,
"child": {
"value": "foo",
"other": 789,
"child": {
"value": "larry",
"other": 123
}
}
}
];
function getFlattenedObject(object){
var response = [];
flatten(object, response, 0);
return response;
}
function flatten(object, array, index){
if(!array[index]){
array.push([]);
}
array[index].push(object);
if(object.child){
flatten(object.child, array, index + 1);
object.child = undefined;
}
}
//Logs for comparison
console.dir(conf)
console.dir(getFlattenedObject(conf));
The result structure you are looking for wasn't "intuitive" and hence the solution has gotten a little ugly, but here is how you could use object-scan to answer your question
// const objectScan = require('object-scan');
const data = [{"value":"baz","threshold":20,"other":123},{"value":"mo","other":456,"child":{"value":"foo","other":789,"child":{"value":"larry","other":123}}}]
const fn = (haystack) => objectScan(['[*]', '**.child'], {
filterFn: ({
key: [id, ...p],
value: { child, ...node },
context
}) => {
if (!(id in context)) {
context[id] = [];
}
context[id].push(child || p.length !== 0 ? [node] : node);
}
})(haystack, []);
console.log(fn(data));
// => [ [ { value: 'baz', threshold: 20, other: 123 } ], [ [ { value: 'larry', other: 123 } ], [ { value: 'foo', other: 789 } ], [ { value: 'mo', other: 456 } ] ] ]
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/object-scan#13.7.1"></script>
Disclaimer: I'm the author of object-scan

How to get a count of a items within a collection that match a specific criteria?

I have a collection like so:
{ "items": [
{
"id": "123",
"meta": {
"activity": 2
}
},
{
"id": "13423",
"meta": {
"activity": 4
}
}
]}
Given the collection, how can I get the collection's total activity? In the case above the result would be 6.
I'm using backbone and underscore.
You're using underscore.js, so you have some good tools at your disposal. Look at _.map() to get started.
var flatArray = _.map(collection.items, function(x){return x.meta.activity;});
// should return: [2,4]
Then you can use _.reduce() to turn this into a single value.
var total = _.reduce(flatArray, function(memo, num) {return memo + num;}, 0);
// should return: 6
There's lots of other great tools in underscore.js, it's worth a look to see if anything else would work for you too.
In underscore you can use the reduce function which will reduce a list of values into a single value using the given iterator function.
var myCollection = { "items": [
{
"id": "123",
"meta": {
"activity": 2
}
},
{
"id": "13423",
"meta": {
"activity": 4
}
}
]};
var totalActivity = _.reduce(myCollection.items, function(memo, item){ return memo + item.meta.activity; }, 0);

Resources