How to create an object of arrays in javascript - javascript

I have a collection in mongodb with a value o type array with 12 rows in it. See the screenshot:
In my code make an axios request in the componentDidMount and successfully get the respone and values
async componentDidMount() {
const {data: locations} = await axios.get('http://localhost:4000/try1');
this.setState({locations})
console.log(locations)
// Use processCsvData helper to convert csv file into kepler.gl structure {fields, rows}
const data = Processors.processCsvData(nycTrips);
console.log(data)
// Create dataset structure
const dataset = {
data,
info: {
// `info` property are optional, adding an `id` associate with this dataset makes it easier
// to replace it later
id: 'my_data'
}
};
// addDataToMap action to inject dataset into kepler.gl instance
this.props.dispatch(addDataToMap({datasets: dataset}));
}
The problem is I am getting the location object like shown in this screenshot:
but my required output is as shown below:
I need the required output to pass it to my mapping application so that the map markers can be generated.
Please advise how I can create an object in the required format.
Following is my simple get api:
app.get('/try1', (req, res) => {
try1.find()
.then(data => res.json(data))
})
Thanks in advance guys.

Related

How do I modify an array in front-end and write back to Firestore

I'm making a to-do style app. I have a createCard function that should do three things.
Read my firestore doc
Modify my labels array
Write it back to firestore
Here's my current code:
const createCard = async (name, tags) => {
// READ FIRESOTRE DOC
const querySnapshot = await getDoc(doc(db, "users", currentUser.uid));
// MODIFY LABELS ARRAY IN FRONT-END
console.log(querySnapshot.data().labels[activeLabel]);
const newCard = querySnapshot
.data()
.labels[activeLabel].cards.push({ name: name, tags: tags });
// WRITE MODIFIED ARRAY BACK TO FIRESTORE
await updateDoc(doc(db, "users", currentUser.uid), {
newCard,
});
console.log(newCard);
console.log(labels);
getCards();
console.log("Tags Created");
};
My desired functionality is for the function to re-write the first (0) array for 'NBA' with an addition of a 3rd card that includes name and tags:
Instead my function does this, indicated with the blue arrow. I have no idea why newCard = 3?:
Let me know if I'm missing key information that would be helpful for adding context to my question. Thank you in advance for any advice or help formatting.

How do I save an object in IndexedDB?

I want to store my API data in indexedDB of Browser. I would have tried local storage but it has a limit of 5MB but my JSON data is more than 7MB. I want to save in indexedDB for faster access. I want to save the whole data in the JSON format but don't know how to set the scheme of the indexed DB. The data fetched from the database is testData
const db =new Dexie("ReactDexie");
db.version(1).stores({
test:"++id title " //Dont Know how to set scheme here for my json object
})
db.open().catch((err)=>{
console.log(err.stack || err)
})
var transaction = db.transaction([testData], IDBTransaction.READ_WRITE);
var objstore = transaction.objectStore(testData);
for (var i = 0; i < testData.length; i++) {
objstore.put(testData[i]);
}
Follow these steps for good architecture and reusable components ( Sample project is created here ):-
1 ) Create one file lets just name it indexDB.js
import Dexie from 'dexie';
const db = new Dexie('ReactDexie');
db.version(1).stores({
testData: 'datakey'
});
export default db;
2 ) Now make one utility function that will store API data (let's assume this is in file utility.js)
import db from './indexDB.js';
export async function saveDataInIndexDB(data) {
if (data) {
if (db.testData) db.testData.clear();
db.testData.add({ datakey: 'datakey', data }).then(() => {});
}
}
3 ) function for fetching data from indexDB (in utility.js file)
export async function getDataFromIndexDB() {
const testData = await db.testData
.where('datakey')
.equals('datakey')
.toArray();
if (testData && testData.length > 0) {
return testData[0];
}
return null;
}
4 ) I am considering sample JSON data as following (suppose you are getting this data in App.js)
const sampleJSONdata = {
type: 'articles',
id: '1',
attributes: {
title: 'JSON:API paints my bikeshed!',
body: 'The shortest article. Ever.',
created: '2015-05-22T14:56:29.000Z',
updated: '2015-05-22T14:56:28.000Z'
}
};
5 ) Store and Fetch data as following (you can call utility.js functions in `App.js file)
saveDataInIndexDB(sampleJSONdata);
const getDataFromDB = async () => {
let data = await getDataFromIndexDB();
console.log('Data ', data);
};
console.log(getDataFromDB());
The sample project is created here, you can refer to this project for further use, more about schema and useful Dexie related article you can find here.
Note*- Please clear site data, you might face multiple version issues as you were trying earlier (in that case you can change or add extraversion)

mongoosejs - find() using nested objects

question is possibly a duplicate but I haven't found anything that provides an appropriate answer to my issue.
I have an ExpressJS server which is used to provide API requests to retrieve data from a MongoDB database. I am using mongoosejs for the MongoDB connection to query/save data.
I am building a route that will allow me to find all data that matches some user input but I am having trouble when doing the query. I have spent a long while looking online for someone with a similar issue but coming up blank.
I will leave example of the code I have at the minute below.
code for route
// -- return matched data (GET)
router.get('/match', async (req, res) => {
const style_data = req.query.style; // grab url param for style scores ** this comes in as a string **
const character_data = req.query.character; // grab url param for character scores ** this comes in as a string **
// run matcher systems
const style_matches = style_match(style_data);
res.send({
response: 200,
data: style_matches
}); // return data
});
code for the query
// ---(Build the finder)
const fetch_matches_using = async function(body, richness, smoke, sweetness) {
return await WhiskyModel.find({
'attributes.body': body,
'attributes.richness': richness,
'attributes.smoke': smoke,
'attributes.sweetness': sweetness
});
}
// ---(Start match function)---
const style_match = async function (scores_as_string) {
// ---(extract data)---
const body = scores_as_string[0];
const richness = scores_as_string[1];
const smoke = scores_as_string[2];
const sweetness = scores_as_string[3];
const matched = [];
// ---(initialise variables)---
let match_count = matched.length;
let first_run; // -> exact matches
let second_run; // -> +- 1
let third_run; // -> +- 2
let fourth_run; // -> +- 3
// ---(begin db find loop)---
first_run = fetch_matches_using(body, richness, smoke, sweetness).then((result) => {return result});
matched.push(first_run);
// ---(return final data)---
return matched
}
example of db object
{
_id: mongoid,
meta-data: {
pagemd:{some data},
name: whiskyname
age: whiskyage,
price: price
},
attributes: {
body: "3",
richness: "3",
smoke: "0",
sweetness: "3",
some other data ...
}
}
When I hit the route in postman the JSON data looks like:
{
response: 200,
data: {}
}
and when I console.log() out matched from within the style match function after I have pushed the it prints [ Promise(pending) ] which I don't understand.
if I console.log() the result from within the .then() I get an empty array.
I have tried using the populate() method after running the find which does technically work, but instead of only returning data that matches it returns every entry in the collection so I think I am doing something wrong there, but I also don't see why I would need to use the .populate() function to access the nested object.
Am I doing something totally wrong here?
I should also mention that the route and the matching functions are in different files just to try and keep things simple.
Thanks for any answers.
just posting an answer as I seem to have fixed this.
Issue was with my .find() function, needed to pass in the items to search by and then also a call back within the function to return error/data. I'll leave the changed code below.
new function
const fetch_matches_using = async function(body, richness, smoke, sweetness) {
const data = await WhiskyModel.find({
'attributes.body': body,
'attributes.richness': richness,
'attributes.smoke': smoke,
'attributes.sweetness': sweetness
}, (error, data) => { // new ¬
if (error) {
return error;
}
if (data) {
console.log(data)
return data
}
});
return data; //new
}
There is still an issue with sending the found results back to the route but this is a different issue I believe. If its connected I'll edit this answer with the fix for that.

How to acces to specific properties into a JSON or Object in JavaScript

I'm making an app in Nodejs using express and node-xlsx module, what I want to do is to make the user able to upload an xlsx file (which has to have an specific format of two columns), an then the server reads it and does something with each row of the file.
(Example of my test file, being the columns A and B respectively):
Johny Wilson | jonhny#email.com
Andrew Jehnsen | andrew#example.com
Billy Soon | billy#mail.com
In order to do this, I've decided to use the node-xlsx module, which, after reading the file with this code:
var xlsx = require('node-xlsx');
router.post('/enviar', upload.single("lista"),(req, res, next) =>{
//dir is the path of the xlsx file
const workSheetsFromFile = xlsx.parse(dir);
res.send(workSheetsFromFile);
});
returns an object that looks like this:
[
{
"name": "Hoja1",
"data": [
[
"Johny Wilson",
"jonhny#email.com"
],
[
"Andrew Jehnsen",
"andrew#example.com"
],
[
"Billy Soon",
"billy#mail.com"
]
]
}
]
As you can see, the module returns the data of all the file, including the sheet's details (In this case only one), I want to access only to the 'data' array which contains keys and values to process them.
I've already tried to loop on the data array with:
workSheetsFromFile.data.forEach((element) =>{
console.log(element);
});
and
workSheetsFromFile[data].forEach((element) =>{
console.log(element);
});
and
workSheetsFromFile['data'].forEach((element) =>{
console.log(element);
});
but all of them just send me an error like "Cannot read property 'forEach' of undefined" or "data is not defined" :(
For now, with those few lines of code I was specting to iterate the data array and print each pair of key and value, so once that is fixed, inside this loop process each key and value in order to send automated mails.
What you have here seems to be an array of objects, not an object itself!
try
workSheetsFromFile[0].data.forEach((element) => {
console.log(element);
});
If you have more elements, consider first looping the array and then extracting data
const structuredData = workSheetsFromFile[0].data.map(res => {
return res
});
workSheetsFromFile.forEach(sheet => {
//access data
console.log(sheet.data)
//or
sheet.data.forEach(data => {
//access each data
console.log(data)
})
})

React Native - How to save map using AsyncStorage

I try to save user inputs as a JS map using AsyncStorage in my React Native app.
It shows no errors when saving, but I got "[object Map]" when I tried to get the data back.
There is the simplified version of my user map. the actual User object has way more properties than this, but the ID is always same as the map key.
const dataKey = 'user-data';
let data = new Map();
data.set(1, { name: 'John', id: 1, title: 'Mr.' })
data.set(2, { name: 'Johanna', id: 2, title: 'Miss.' })
There is the code for saving the data.
async saveDate = (dataKey, data) => {
try {
await AsyncStorage.setItem(dataKey, data.toString());
} catch (err) {
console.log(err);
}
}
There will be more than 200 users in this map.
Any idea how to save complex data structure in react native?
Instead of converting your data to a string you need to save it as JSON. Change
await AsyncStorage.setItem(dataKey, data.toString());
to
await AsyncStorage.setItem(dataKey, JSON.stringify(data));
See this link to the official documents for more details: https://facebook.github.io/react-native/docs/asyncstorage.html#mergeitem
Like one of the other answers states, you need to save the data as JSON.
However, with you won't be able to simply convert data to JSON. Instead you will need to spread the array entries of Map and pass that to JSON.stringify().
So change
await AsyncStorage.setItem(dataKey, data.toString());
to
await AsyncStorage.setItem(dataKey, JSON.stringify([...data]));
And then when you want to get the item from Async you will need to convert it back to Map, i.e.
const jsonData = AsyncStorage.getItem(dataKey)
const mapData = new Map(jsonData)
The provided answers will not quite work. You can't create the new Map after reading back json without parsing first. This works:
saveData = async () => {
const dataKey = 'user-data';
let data = new Map();
data.set(1, { name: 'John', id: 1, title: 'Mr.' })
data.set(2, { name: 'Johanna', id: 2, title: 'Miss.' })
try {
await AsyncStorage.setItem(dataKey, JSON.stringify([...data]));
} catch (err) {
console.log(err);
}
const jsonData = await AsyncStorage.getItem(dataKey)
const parseData = JSON.parse(jsonData)
const mapData = new Map(parseData)
console.log(mapData);
//get a list of IDs
console.log(Array.from(mapData.keys()));
}
For 200 values this is a lot of overhead. I would consider using sprintf/sscanf libraries and just store a string, for instance one row of data per line.
This will only work if every row in the table has the same amount of elements and you don't change the layout. Of course it would all be on you to convert the string back to objects so you can recreate the Map. Just a thought!

Categories

Resources