Appending JSON object inside state of component and displaying it - javascript

I have a function to which I am passing the state of an object. Inside the function I am performing some operations on the state. Now I want to update the state with the operations I have performed and display it as an JSON object.
I have my state as :
state= {
company: "xyz",
employee: {
name:["a","b"],
age: [13,14]
},
details: {
salary:[],
dept:[]
}
}
}
I have a function in which I have populated the values of salary and dept
function updatestate(state){
//some operations..
//const output has values
//output variable has something like this stored in it=>
// salary:[["2500"],["4000"]] , dept:[["fin"],["mkt"]]
}
the state object passed has all the values; now I want to append the values of salary and dept inside filters.
Expected output is :
state= {
company: "xyz",
employee: {
name:["a","b"],
age: [13,14]
},
details: {
salary:[["2500"],["4000"]] ,
dept:[["fin"],["mkt"]]
}
}
}
I tried manual coding:
//inside the function updatestate(state)
const state_json = {details : output}
return JSON.stringify(state_json);
But I want to show the entire state and find a way to automatically append the values into the state and display as JSON

I'm not sure with your issue, but I think you can use JSON.stringify() Fn for the same.
let state= {
company: "xyz",
employee: {
name:["a","b"],
age: [13,14]
},
details: {
salary:[],
dept:[]
}
};
function updatestate(state) {
const baseData = {
salary:[["2500"],["4000"]] ,
dept:[["fin"],["mkt"]]
};
state.details.salary = baseData.salary;
state.details.dept = baseData.dept;
return state;
}
state = updatestate(state);
console.log(JSON.stringify(state));

Related

Imported function not doing what it's supposed to when running jest

DATA STORE FILE:
let data = {
users: [],
channels: [],
};
// Use get() to access the data
function getData() {
return data;
}
// Use set(newData) to pass in the entire data object, with modifications made
function setData(newData) {
data = newData;
}
export { getData, setData };
clearV1() FILE:
import { getData, setData } from './dataStore';
function clearV1() {
let data = {
users: [],
channels: [],
};
setData(data);
return {};
}
export { clearV1 };
When running the clearV1() function in another, it does not clear the data store. For example:
authRegisterV1 creates a user and adds them to the data store
channelCreateV1 creates a channel and adds it to the data store
authRegisterV1('test1#gmail.com','test123','Firt','Last');
clearV1()
authRegisterV1('test2#gmail.com','test123','Firt','Last');
expected output:
{
users: [
{
uId: 1,
email: 'test2#gmail.com',
password: 'test123',
nameFirst: 'Firt',
nameLast: 'Last',
handle: 'firtlast0',
permissionId: 2
}
],
channels: [],
}
wrong output:
{
users: [
{
uId: 1,
email: 'test1#gmail.com',
password: 'test123',
nameFirst: 'Firt',
nameLast: 'Last',
handle: 'firtlast',
permissionId: 1
},
{
uId: 2,
email: 'test2#gmail.com',
password: 'test123',
nameFirst: 'Firt',
nameLast: 'Last',
handle: 'firtlast0',
permissionId: 2
}
],
channels: [],
}
I believe the implementation of the clearV1() function is correct, what other possible reason could there be for this error? I imported all the used functions into the test file.
I think the problem your facing is the fact that you created data inside of ./dataStore, and thus, it does not exist in clearV1() file. Another way to put is, when you made the data variable initially, it was made in ./dataStore and only exists there. So it makes a new variable instead of updating the existing one.
Another problem is, you are trying to using let data = [value]. let creates the variable just inside of the function you called it in, ignoring any variables on the outside. As a rule of thumb in javascript, when updating an existing variable, use [name] = [value].
If you want to learn more, here's the MDN docs for import statements and let statements.

Change a value from a nested object using localstorage

I have this code that set the obj value in localstorage.
const obj = {
name: "Bill",
meta: {
age: 18
}
};
const data = localStorage.setItem('user', JSON.stringify(obj));
Now i want to change the age key in the localstorage:
localStorage.setItem('user', JSON.stringify({ ...data, ...data.meta.age= 15 } }));, but it does not work.
How to change the value above and to see the changes in localstorage?
Assuming you have data, the problem is that ...data.meta.age = 15 is a syntax error. You don't use = in object literals, and it does't make sense to try to spread the age property (which is a number). Instead:
const newData = {
...data,
meta: {
...data.meta,
age: 15,
},
};
localStorage.setItem("user", JSON.stringify(newData));
Notice how we have to create a new outermost object and also a new object for meta.
Live Example:
const data = {
name: "Bill",
meta: {
occupation: "Programmer", // Added so we see it get copied
age: 18,
},
};
const newData = {
...data,
meta: {
...data.meta,
age: 15,
},
};
console.log(newData);

filter function shows an empty array

I want to create a search filter. The way it works is a user inputs a text in the search bar, the input is stored using vuex and the result is shown in a different page. Here's an array of objects in a js file
export const productData = [
{
id: 1,
name: "table",
materials: "wood"
},
{
id: 2,
name: "table2",
materials: "metal"
},
{
id: 3,
name: "chair",
materials: "plastic"
}
]
I want to filter using the user's input. Here's my function
import { productData } from '#/data/productData'
export default {
data() {
return {
products: productData
}
},
computed: {
userInput() {
return this.$store.state.userInput
},
filterProducts: function() {
return this.products.filter(q => q.name.match(this.userInput))
}
}
}
When I console the userInput, it works fine! So the problem is in the filterProducts function. It shows an empty array if I console it. What am I doing wrong? Thank you.
edit: the reason I make a new variable called products is because the actual js file is more complex so I had to flatten the array. But the flatten process works fine so I thought I would just simplify the question.
The match function accepts a regex, not String. Give indexOf a try:
filterProducts: function() {
return this.products.filter(q => q.name.indexOf(this.userInput) >= 0)
}

How to load mobx state from json?

I want to store my mobx state in browser localStorage, so, if i use this approach https://stackoverflow.com/a/40326316
I save store with toJS, but don't know how to apply it. With extendObservable I get following error Error: [mobx] 'extendObservable' can only be used to introduce new properties. Use 'set' or 'decorate' instead
Thanks in advance.
My approach is:
class MyStore {
...
public async load() {
const cached = await browser.storage.local.get("cache");
const data = JSON.parse(cached["cached"]);
Object.keys(data).forEach(x => {
(this as any)[x] = (data as any)[x];
});
...
}
But i think this is anitpattern.
Are you sure extendObservable doesn't work.
I've used something like this in my code.
class MyStore {
async load() {
const cached = await browser.storage.local.get("cache");
mobx.extendObservable(this, cached);
}
}
Edit:
This seems to be not working, you need to access the properties after extendObservable in order to reload them, you could use autorun but just use another method.
I've implemented load function based on a simple forEach;
Try the following.
load = async () => {
const { cache } = await JSON.parse(localStorage.getItem("cache"));
Object.keys(cache).forEach(key => {
this[key] = cache[key];
});
};
CodeSandbox
https://codesandbox.io/s/late-snow-xppx0?ontsize=14&hidenavigation=1&theme=dark
If you have a class, and "raw" json data, what i'm doing is to accept raw data in the constructor & then update the class properties.
For example, my raw data looks like this:
{
users: [
{ id: 1, firstName: 'foo', lastName: 'bar', customer: { id: 1, name: 'bla' } },
{ id: 2, firstName: 'foo2', lastName: 'bar2', customer: { id: 2, name: 'customer' } },
];
}
class User {
id;
#observable firstName;
#observable lastName;
customer;
constructor(rawUser) {
this.id = rawUser.id;
this.firstName = rawUser.firstName;
this.lastName = rawUser.lastName;
this.customer = new Customer(rawUser.customer);
}
}
class UsersStore {
#observable users = [];
constructor(rawUsers) {
this.users = rawUsers.map(rawUser => new User(rawUser));
}
}
Then when I'm restoring the data I'm just using
const usersStore = new UsersStore(rawData.users);
The cool thing in this approach is the nesting handling, each "level" handles its part.

Javascript push into an object

I have been trying this fora a little while and cannot get it.
I have a piece of code to create an Array of an objects which is something like this :
var allUsers = new Array();
function addObjectToArray(userData){
colorCode = '#'+Math.floor(Math.random()*16777215).toString(16);
userImage = "avatar"+Math.floor(Math.random()*11)+".jpg";
newuserData = {};
newuserData[userData.userID] = {"nickName":userData.nickName,"SocketId":socket.id,"colorCode":colorCode,"userImage":userImage};
allUsers.push(newuserData);
}
So this function adds a new Object to array everytime it is called and after calling this function twice with different params i get an array something like this
[ { '886':
{ nickName: 'MOhan',
SocketId: '9AMRe2v2e-hWuMeBAAAC',
colorCode: '#d3af07',
userImage: 'avatar6.jpg' } },
{ '172':
{ nickName: 'Anil',
SocketId: 'a5VU5pCzWecMHM2FAAAD',
colorCode: '#22b913',
userImage: 'avatar4.jpg' } } ]
What i want instead is an object something like this :
{
'886':
{ nickName: 'MOhan',
SocketId: '9AMRe2v2e-hWuMeBAAAC',
colorCode: '#d3af07',
userImage: 'avatar6.jpg' } ,
'172':
{ nickName: 'Anil',
SocketId: 'a5VU5pCzWecMHM2FAAAD',
colorCode: '#22b913',
userImage: 'avatar4.jpg' }
}
What changes should i make to the code.
Easy, objects aren't technically pushed to but instead you define new keys on that object.
Switch your Array for an object literal and just add the key to it.
var allUsers = {};
function addObjectToObject(userData) {
//logic
allUsers[userData.userId] = newuserData;
}

Categories