How to delete key:value pair from req.user object - javascript

Why does the delete operator on the req.user object not work?
let test = new Object(req.user);
console.log(test.password); // Get correct string
delete test.password;
console.log(test.password); // Get correct string, but expect undefined

This works for me
let test = {user:"hello", password:"goodbye"};
console.log(test.password);
// output is: hello
delete test.password;
console.log(test.password);
// output is: undefined
Could you edit post a snippet with an explicit assignment at the top (rather than a reference to req.user, which we can't reproduce). See if the problem reproduces with that.

Use new Object() on an existing object, doesn't actually create a new object. All you get is a reference to the original one.
The original object (req.user) might have the password field as part of it's prototype, and not as an own property. Deleting it from the object does nothing, because it's not a part of the object.
Demo:
const base = Object.create({user:"hello", password:"goodbye"});
const test = new Object(base);
console.log(test === base); // true - it's the same object
console.log({ pass: test.password, ownProp: test.hasOwnProperty('password') });
delete test.password;
console.log({ pass: test.password, ownProp: test.hasOwnProperty('password') });

This line just creates a reference to an existing object:
let test = new Object(req.user);
It's the same thing as
let test = req.user;
So whether or not you can delete test.password depends on whether or not you can delete req.user.password (it's the same operation). If req.user.password is not a writable property, you will get the behavior you describe.
const req = {
user: {}
};
Object.defineProperty(req.user, "password", {
value: "123456",
writable: false
});
let test = new Object(req.user);
console.log(test.password); // Get correct string
delete test.password;
console.log(test.password); // Get correct string, but expect undefined
const req2 = {
user: {
password: "123456"
}
};
let test2 = new Object(req2.user);
console.log(test2.password); // Get correct string
delete test2.password;
console.log(test2.password); // This works as expected

Related

Pass a string as a parameter in JS

This is pretty simple, I'm trying to insert a value that has a string as a parameter.
Let's give an example:
const stringName = "User".
and my goal is to activate a function that gonna be called like that
User.find();
I tried the follows without success: stringName.find() but didn't worked and also [stringName].find()
Why I want to do that: I receive a param that is a string, and I want to search with this param in my DB so the real query gonna be something like that: param.findAll({where....})
I'm sure that there is a simple solution like the examples above. hope for help.
You can store User in an object, and then access it with the string.
const myObjects = {
User: User,
// Post: Post, ...
}
const stringName = "User"
myObjects[stringName].find('foo')
You probably could do something like this:
let fncName(clsName) {
if(window[clsName]) {
let cls = new window[clsName]();
cls.find();
}
}
This however requires all classes that you are calling to have a function named find. Probably better to do a switch on the passed in string and go from there.
let fncName(clsName) {
switch(clsName) {
case 'User':
User.find();
default:
...
}
}
You can't simply execute .find() on a string unless you define the find() method in string prototype.
If your goal is to execute some methods of an object, and that object's name you are getting as a string.
If that object is available in your current context:
const param = "User";
this[param].find()
If object is not available in current context:
let objectMap = {
"user": USER
};
let param = "user";
objectMap[param].find();

How can I delete the proper object property value in JS

I am working through a little practice assignment and have come across this question and for the life of me can't figure it out.
There are tests parameters that I can't see. The object is not a variable I can see, it's just assumed.
Write a function called removePassword that takes in an object.
Delete the property password and return the object.
removePassword=(object)=>{
for(var key in object){
if(object = object[key]){
delete object[key]
}
}return object;
}
I have tried a bunch of different versions of this code, but I don't know how to just delete the property password only without deleting the other property which is a username
Take a look at this solution. You can avoid doing the object copy if you want, it'll work anyway
const removePassword = (user) => {
const userCopy = {...user} // CREATE A COPY OF THE OBJECT
delete userCopy.password // DELETE THE PASSWORD PROPERTY
return userCopy // RETURN UPDATED USER
}
const testUser = {username: 'Mario', password: 'supersecret123'}
console.log(
removePassword(testUser)
)
Could it work for you?
removePassword = (object) => {
delete object.password;
return object;
}
You can see here link
That you can do it simply delete object.password or delete object["password"] :
const removePassword = (object) => {
delete object.password;
return object;
}

How to destructure an object that is stored as a state value

Within a React App component, I am calling an API and storing the response within a local state. I then want to destructure the object that is stored in that state, but I can't just destructure right below the useEffect because it will throw an error before the call is completed.
Also, I don't want to break up the object within the useEffect, because I want the entire response for other things.
Here is an example:
const MyComponent = () => {
const [calledObj, setCalledObj] = useState({})
useEffect(() => {
//Calling API here and setting object response as calledObj State
setCalledObj(apiResponse)
}, []);
//This will throw an error when the API response has not been sent back yet.//
// While this would be easy to write the whole path in the return, the actual path is really long.//
const { name } = calledObj.person
return (<div>{name}</div>)
}
Where can I destructure or how can I work around this?
You can use optional chaining and/or the nullish coelescing operator to work around it.
Note: IE doesn't support either of these, but babel will polyfill them.
const { name } = calledObj?.person ?? {};
The optional chaining (the ?. in calledObj?.person) prevents it from blowing up if calledObj is undefined.
The nullish coalescing operator (??) returns {} if calledObj.person isn't there.
With this combination the right side is guaranteed to evaluate to an object, so the destructuring on the left never blows up.
let calledObject; // undefined;
// name is undefined, but it doesn't blow up.
const { name: name1 } = calledObject?.person ?? {};
console.log(`name 1: ${name1}`); // name 1: undefined
// ----------------
// now it's an object, but doesn't have a person property
calledObject = {};
// name is still undefined, still doesn't blow up.
const { name: name2 } = calledObject?.person ?? {};
console.log(`name 2: ${name2}`); // name 1: undefined
// ----------------
// with person.name present…
calledObject.person = { name: 'joe' };
const { name: name3 } = calledObject?.person ?? {};
// …it works as you'd expect
console.log(`name 3: ${name3}`); // name 3: 'joe'
Depending on what you want your name variable to default to on first render, I guess you could do something like this:
const { name } = calledObj.person ? calledObj.person : {name: ''}
You can initialize your state with:
const [calledObj, setCalledObj] = useState({person: {}})
And this will put undefined in 'name' but is not breaking your code.

Modifying javascript class attributes

What i am trying to do here is, I have the following class Session
function Session(){
this.accounts = {};
this.setupAccounts = function(res){
this.accounts = res;
log(res);
log(this.accounts);
};
this.test = function(){
log(this.accounts);
};
}
The class Session has an attribute accounts, which will keep store certain data. But in order to initialize it, i initialize it as an empty object.
Next I call the method setupAccounts to modify the value of accounts. For example, I read a file, load it's data and then store that data inside accounts.
But I am having scope problems.
For example the following code :
var session = new Session();
var user_account_path = '/adata/user_accounts.json';
loadJsonFile(user_account_path)
.then(session.setupAccounts);
session.test();
So what i am doing in the code above is fetching the contents of a file as a Json Object and then I am passing that data to the method setupAccounts in order to store that data in the variable accounts. But my output looks like the following:
Object {arjrule3: Object} // printing the json object read from file
Object {arjrule3: Object} // locally changed value of accounts
console.log(session.accounts) // printing global value of accounts
{} // value has not changed.
What am i doing wrong? Why isn't the value for accounts changing for the object session ?
Something Funny just happened, if i write the code as the following:
var session = new Session();
var user_account_path = '/adata/user_accounts.json';
loadJsonFile(user_account_path)
.then(function(res){
session.setupAccounts(res); // Change Here
});
Output:
Object {arjrule3: Object}
Object {arjrule3: Object}
session.accounts
Object {arjrule3: Object} // works! Why ?
It works, why is it so ?
var session = new Session();
var user_account_path = '/adata/user_accounts.json';
loadJsonFile(user_account_path)
.then(session.setupAccounts);
session.test();
In the above example you're just passing the function "setupAccounts" as the callback. You would need to bind it first e.g.
var session = new Session();
var user_account_path = '/adata/user_accounts.json';
loadJsonFile(user_account_path)
.then(session.setupAccounts.bind(session));
session.test();
The other example you've added works because you're calling the "setupAccounts" function on the session object, not just passing a reference to it.

Variable assigned to the property of a global object not updating

I'm running into an issue where a variable assigned to the property of a global object does not get updated. I know this is some kind of javascript pass by reference issue that i'm not understanding, despite having looked through some other similar SO questions. Here's the some code I wrote to test this scenario:
function formState (type) {
this.current_form = { primary:null};
this.set_primary = function(form) {
this.current_form.primary = form;
return this.current_form.primary;
};
}
var schedule = function(someState) {
someState.set_primary({"updated":"updated"});
};
var state = new formState();
var newState = state.set_primary({"new":"new"});
console.log("newState = ", newState);
schedule(state);
console.log("newState = ", newState);
A console.log at the end shows that newState = { new: 'new' }. Why is this? If newStateis referencing a block of memory, shouldn't I be able to update that memory from anywhere and have the changes be reflected in newState? I'm missing something fundamental here, any help would be appreciated.
Here's the corresponding repl.
You set newState equal to {new:'new'} with this line:
var newState = state.set_primary({"new":"new"});
Note that newState does not hold any reference to state or to state.current_form
So when you run this line:
schedule(state);
It changes state.current_form.primary, but it has no effect on the { new: 'new' } object that was assigned to newState.
If you WANT to see a change you can do this:
var state = new formState();
var newState = state.current_form;
state.set_primary({"new":"new"});
console.log("newState = ", newState.primary);
schedule(state);
console.log("newState = ", newState.primary);
this will print:
newState = { new: 'new' }
newState = { updated: 'updated' }
Note the difference. In this version of the code, newState is set to the current_form object which is not replaced by the call to set_primary. Now, when state.current_form.primary is set to reference the object {updated:'updated'}, newState.primary points to the updated object.
At first, this.current_form.primary refers the object {"new":"new"} and that is returned to be assigned in newState. At this point both newState and this.current_form.primary refer the same object. You can confirm that like this
console.log(newState === state.current_form.primary);
But, the next time, when you call schedule, it assigns a new object to current_form.primary. So, current_form.primary and newState point to different objects now. That is why newState still shows {new: "new"}.

Categories