I am new javascript. I could do this in 2 seconds in python/java but I am struggling here. I am developing an reactJS app. I am retrieving a string which is a dictionary/HashMap<String, ArrayList> from a server via axios. I get response.data and my data is in the form:
{ "key1": [1,23,4,5,5,2],
"key2": [2,6,5,5,5,6,5],
...
}
I want to convert this into a map/dictionary so I can access it like so (get(), keys(), etc.
However, i am having trouble doing this.
console.log(typeof data) gives me string.
And when I JSON.parse() or JSON.stringify() and use new Map() i get this weird thing with thousands of integer keys and it doesn't act like I want. Any idea on how I can do this?
Thanks!
EDIT
Here is a more complete code example.
const fetchData = () => {
const url = "http://127.0.0.1:8081/pdata";
const promise = axios.get(url);
console.log(promise);
const dataPromise = promise.then((response) => response.data);
console.log(dataPromise);
return dataPromise;
}
export default function Home() {
//Bind the data to a useState Hook in React, to ensure that we have the correct data
const [data, setData] = React.useState([]);
//This function runs on page reload, twice. Your fetch data function will run repeatedly while contained
//within this functional component.
useEffect(() => {
fetchData().then((apiEndpoint) => {
//setting data equal to the result of the FetchData function
setData(apiEndpoint);
}).catch(err => console.log(err))
}, [])
// We now have the data.
// Convert it to a map
const map = new Map(Object.entries(data));
console.log(map.get("Model Used"));
console.log([...map.keys()]);
At point We now have the data, console.log(data) prints the incoming data correctly its just is of type string not map or whatever javascript calls it.
Using Map and Object#entries:
const obj = { "key1": [1,23,4,5,5,2], "key2": [2,6,5,5,5,6,5] };
const map = new Map(Object.entries(obj));
console.log(map.get("key1"));
console.log([...map.keys()]);
From https://flexiple.com/javascript/javascript-dictionary/
Are there dictionaries in JavaScript? No, as of now JavaScript does not include a native “Dictionary” data type. However, Objects in JavaScript are quite flexible and can be used to create key-value pairs. These objects are quite similar to dictionaries and work alike.
It seems you can just parse the string that you obtained to JSON and use the parsed object obtained. For example:
var api_response = `
{
"key1": [1,23,4,5,5,2],
"key2": [2,6,5,5,5,6,5]
}`;
var parsed_data = JSON.parse(api_response);
console.log(Object.keys(parsed_data))
console.log(parsed_data["key2"])
console.log(parsed_data.key1)
Related
So I have an array with the following structure:
`
export const transacciones = [
{
id:100,
cantidad: 0,
concepto : 'Ejemplo',
descripcion: 'Ejemplo',
},
]
`
This array will dynamically increase or decrease as I push or filter items in it (Exactly like data in a task list)
The problem is that I am trying to add some data persistence using local storage. I guess data is getting stored but not shown when I refresh my browser (chrome).
However, when I refresh data disappears from where it was in the upper image so I`m not even sure if I am correctly storing it.
I've tried two things using useEffect hooks.
First aproach:
`
const [transacciones,setTransacciones] = useState([]);
useEffect(()=>{
localStorage.setItem('transacciones',JSON.stringify(transacciones))
},[transacciones])
useEffect(() =>{
const transacciones = JSON.parse(localStorage.getItem('transacciones'))
if (transacciones){
setTransacciones(transacciones)
}
},[])
`
I read somewhere that as the initial value of use state is [] I should chage things in there, so...
Second aproach:
`
const [transacciones,setTransacciones] = useState([],()=>{
const localData = localStorage.getItem('transacciones');
return localData ? JSON.parse(localData) : [];
});
useEffect(()=>{
localStorage.setItem('transacciones',JSON.stringify(transacciones))
},[transacciones])
`
However, when I refresh I get the same result: No persistence.
What am I missing here? Any help would be appreciated
In both scenarios your transacciones array is empty when you perform the localStorage.setItem. if you're trying to keep your local state sync with localStorage this might help:
export function useTransacciones(initialValue){
const localData = localStorage.getItem('transacciones');
const [transacciones,_setTransacciones] = useState(localData?JSON.parse(localData) : initialValue); // you can choose your own strategy to handle `initialValue` and cachedValue
const setTransacciones = (data) => {
_setTransacciones(data)
localStorage.setItem(JSON.stringify(data))
}
hydrate(){
const data = localStorage.getItem("transacciones")
setTransacciones(JSON.prase(data))
}
return [ transacciones, setTransacciones, hydrate ]
}
which you can use it anywhere with caching compelexity hidden inside:
const [transacciones, setTransacciones] = useTransacciones([])
How can I access array data inside my json object data?
const [data, setData] = useState([])
const getData = () => {
axiosInstance
.get(url + slug)
.then(result => setData(result.data))
}
useEffect(() => {
getData()
}, [])
Here are something I've tried:
console.log(data['symbol'])
console.log(data[0]['symbol'])
console.log(data[0].symbol)
Here is the data being used in my state:
To keep it simple, lets say I want to the access first array, and console log all values for symbol. How would I go about doing that?
Your object data looks like an array of arrays of objects.
This should work:
data[0][0].symbol
To log all the symbols of the first array:
console.log(data[0].map(item => item.symbol))
To access the first array you can use this data[0] to map through all the objects inside the first array and log them you do the following
data[0].map(item => console.log(item.symbol))
So I have a payload that pushes firestore collection to an object. Currently when I console.log the object, it shows:
I need it to be in just 1 array, how do I go about that?
I need it to look like (image below) so I can use it with my vuetify data tables
My vuex goes like this:
mutations: {
firebaseOrders(state, payload) {
state.firebaseOrders.unshift(payload)
},
actions: {
getFireBaseOrders(state) {
db.collection("orders").onSnapshot((res) => {
const changes = res.docChanges();
changes.forEach((change) => {
// Push all data to firebaseOrders[]
let payload = change.doc.data();
state.commit("firebaseOrders", payload);
...
This joins the two arrays together.
new_array = old_array[0].concat(old_array[1])
Reference: MDN Web Docs
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!
Using REST, I am retrieving an object(JSON format) which is to be converted to an array so that it can be inserted into a table.
This is done in the rendering function of React.
The input is updated every N minutes from the back-end.
How do I convert an object to an array?
I need only the values, not the keys, since the keys are already present as column values beforehand in the table itself.
You can use Object#values (ECMAScript 2017), but it's not supported by IE (see browser's compatibility).
Note: The ECMAScript 6 specification defines in which order the properties of an object should be traversed. This blog post explains the details.
const map = { a: 1, b: 2, c: 3 };
const result = Object.values(map);
console.log(result);
If you need to support IE, you can use Object#keys with Array#map:
const map = { a: 1, b: 2, c: 3 };
const result = Object.keys(map).map((key) => map[key]);
console.log(result);
I am not sure by map you mean the Map object or an ordinary JS object. However, just for variety I would like to mention that the Map objects are mostly (probably always) stringified like JSON.stringify([...myMap]). So if you happen to receive a Map object in JSON data may be you should do something like;
var myMap = new Map().set(1,"hey").set(2,"you"),
mapData = JSON.stringify([...myMap]),
values = JSON.parse(mapData).map(d => d[1]);
console.log("mapData:",mapData);
console.log("values:",values);
You can set initial value as array firstly. See this example:
const [conversations, setConversations] = useState([]); // fianal data is array
useEffect(() => {
const fetchConversations = async () => {
const res = await axios.get("/conversations/" + user._id);
setConversations(res.data);
};
fetchConversations();
}, [user._id]);
res.data convert to array by using useState([]) as initial value and convert to object by using useState({}).
And
return(
{conversations.map((conv) => (
))}
)
You can set initial value as array firstly. See this example:
const [conversations, setConversations] = useState([]); // fianal data is array
useEffect(() => {
const fetchConversations = async () => {
const res = await axios.get("/conversations/" + user._id);
setConversations(res.data);
};
fetchConversations();
}, [user._id]);
res.data convert to array by using useState([]) as initial value and convert to object by using useState({}).
And map this array:
return (
<>
{conversations.map((conv) =>
(<Conversations key={conv._id} conversation={conv} />))}
</>
)