const root = {
user: (id) => {
console.log("returning object " + JSON.stringify(id.id) + " " + JSON.stringify(storage.select("users", id.id)))
return storage.select("users", id.id)
}
}
I want to call the arrow function in root.user but I think I can't pass the parameter correctly, so I tried this --> let user = root.user('101')
and on the console I got this -->
returning object undefined
[{"firstName":"Gokhan","lastName":"Coskun","login":"gcoskun","id":101}]
{"firstName":"George","lastName":"Clooney","login":"gclooney"}
[{"firstName":"Gokhan","lastName":"Coskun","login":"gcoskun","id":101}]
I wanted the user with the id 101 get returned and got instead all of the users returned.
Why are you doing id.id but passing a string? You either pass an object with an id prop (root.user({ id: '101' })) or replace id.id with simply id.
Also, it looks like the id fields in your user objects are of type number, while you are passing a string, so depending on the logic inside storage.select you might have to change that.
Passing a number id:
// Just mocking it for the example:
const storage = {
select(key, id) {
return [
{ firstName: 'Gokhan', lastName: 'Coskun', login: 'gcoskun', id: 101 },
{ firstName: 'George', lastName: 'Clooney', login: 'gclooney' },
{ firstName: 'Gokhan', lastName: 'Coskun', login: 'gcoskun', id: 101 },
// Depending on the logic here, these types need to match.
// Using == instead of === so that it's not required here.
].filter(user => user.id == id)
},
};
const root = {
user: (id) => {
console.log(`ID = ${ id }`);
// We make sure we only return a single user or null if there isn't one:
return storage.select('users', id)[0] || null;
},
};
const user = root.user('101');
console.log(user);
Passing an object with an id prop of type number:
// Just mocking it for the example:
const storage = {
select(key, id) {
return [
{ firstName: 'Gokhan', lastName: 'Coskun', login: 'gcoskun', id: 101 },
{ firstName: 'George', lastName: 'Clooney', login: 'gclooney' },
{ firstName: 'Gokhan', lastName: 'Coskun', login: 'gcoskun', id: 101 },
// Depending on the logic here, these types need to match.
// Using == instead of === so that it's not required here.
].filter(user => user.id == id);
},
};
const root = {
user: (query) => {
console.log(`ID = ${ query.id }`);
// We make sure we only return a single user or null if there isn't one:
return storage.select('users', query.id)[0] || null;
},
};
const user = root.user({ id: '101' });
console.log(user);
Related
I have a function in my context that takes in two data points, the current username and the username of a randomly selected user who is online
const pairProgrammingMatching = (username, matchedUser) => {
setPairUsers({username: matchedUser })
}
I call this function in another component using useEffect()
useEffect((() => {
console.log('curr username is', username)
pairProgrammingMatching(username, checkOnlineUsers(pickRandom()).username)
console.log('inside pairUsers state', pairUsers)
}), [])
checkOnlineUsers simply returns a list of all users who are currently online and active
let checkOnlineUsers = () => {
const results = onlineUsers.filter(obj => {
return obj.profile.is_online === true && obj.profile.currently_active === false && obj.username !== user.username
})
return results
}
Here's a sample of what this function returns
[{ email: "***#gmail.com"
first_name: ""
last_name: ""
profile: {city: 'Washington DC', country: 'USA', is_online: true, currently_active: false}
username: "testingUser" }]
pickRandom simply picks a number between 0 and n, with n being the number of users returned in checkOnlineUsers:
const pickRandom = () => {
return Math.round(Math.random()*onlineUsers.length)
}
The problem here is that if I print out pairUsers inside my useEffect I expect to see this:
{ 'userA': 'testingUser' }
with userA being the name of the current user. However this is what I get:
{username: undefined}
I am trying to check if the items in one list (list A) are contained in another other list (list B), and if they are, a property/field of the corrisponding items in list B should change its boolean values.
Here is my code:
export default defineComponent({
name: 'Users',
props: {
existingUsers : {
type: Array as PropType<Array<UserModel>>,
}
},
async setup(props) {
const allUsers = ref<Array<UserModel>>(await userService.list())
const userList = ref<Array<UserModel>>([{ id: 0, email: '', first_name: '', last_name: '', }])
function defineUsers(): Array<UserModel> {
if (props.existingUsers) {
const existingUsers = props.existingUsers
userList.value = allUsers.value
.map((user: UserModel) => existingUsers
.forEach((us: UserModel) => (us.id === user.id) ? user.isSelected = true : user)))
return userList.value;
} else {
userList.value = allUsers.value
return userList.value
}
}
defineUsers();
Basically, if there are no existing users passed as props then the userList equals allUsers (which gets values from a GET request to an API). If there are existing users passed as props, then the variable allUsers shall be modified accordingly: each user in allUsers that is contained in existingUsers needs to set it 'isSelected' value to true.
This is the error I get related to userList.value on line 3 inside the function defineUsers:
Type 'ComputedRef<void[]>' is missing the following properties from type '{ id: number; email: string; first_name: string; last_name: string; organization?: { id: number; company_name: string; address: string; postal_code: string; city: string; state: string; country: string; vat: string; fiscal_code?: string | undefined; codice_sdi?: string | undefined; registration_date?: string | undef...': length, pop, push, concat, and 28 more.Vetur(2740)
Any clue on how to solve this?
Thanks a lot.
you can't use the .forEach method as return type, you need to do something like this
userList.value = allUsers.value.map((user: UserModel) =>
existingUsers.map((us: UserModel) => {
user.isSelected = us.id === user.id;
return user;
})
);
let me know if this work!
This is how I solved it:
function defineUsers(): Array<UserModel> {
if (props.existingUsers) {
const existingUsers = props.existingUsers
userList.value = allUsers.value.map((user: UserModel) => {
let isSelected = existingUsers.some((us: UserModel) =>
us.id === user.id
);
user.isSelected = isSelected;
return user;
});
return userList.value;
} else {
return allUsers.value;
}
}
I have a Type described in typescript like this -
export type User = {
name: string;
username: string;
phoneNumber: string;
personalEmail?: string;
workEmail?: string
}
I'm fetching some data from a json file which consists of objects like these and shaping the data to this type User for each object with this function
const shaper = (obj: any): User {
const user: User = {
name: obj.name,
username: obj.username,
number: obj.number,
personalEmail: obj.personalEmail,
workEmail: obj.workEmail,
}
// remove from user the fields which have value === undefined
return user;
}
In the shaper function, I want to remove the fields of the variable user which have the value as undefined (eg : obj.personalEmail does not exist)
How do I achieve this?
Here you have a working example.
You can use delete obj[key]
const shaper = (obj) => {
const user = {
name: obj.name,
username: obj.username,
number: obj.number,
personalEmail: obj.personalEmail,
workEmail: obj.workEmail,
}
Object.entries(user).forEach(([key, value]) => {
if (value === undefined) {
delete user[key];
console.log("deleted", key);
}
});
return user;
}
const shapedResult = shaper({
name: "foo",
workEmail: "bar#bar.com"
});
console.log(shapedResult);
You could do something like this:
/* Test Data */
const test = {
name: 'name',
username: 'username',
needToRename: '123456789',
another: 'blah',
something: 'else',
workEmail: 'hello#example.com'
}
/* Example 1 */
const shaper = ({name, username, needToRename:phoneNumber, personalEmail, workEmail}) => {
return {
name,
username,
phoneNumber,
...( personalEmail !== undefined && {personalEmail} ),
...( workEmail !== undefined && {workEmail})
}
}
console.log(shaper(test));
Or you could extract the undefined check into a helper function and do this:
/* Test Data */
const test = {
name: 'name',
username: 'username',
needToRename: '123456789',
another: 'blah',
something: 'else',
workEmail: 'hello#example.com'
}
/* Example 2 */
function undefinedHelper(name, obj) {
return obj[name] === undefined ? {} : {[name]: obj[name]};
}
const shaper2 = (obj) => {
return {
name: obj.name,
username: obj.username,
phoneNumber: obj.needToRename,
...undefinedHelper('personalEmail', obj),
...undefinedHelper('workEmail', obj)
}
}
console.log(shaper2(test));
This answer was helpful: https://stackoverflow.com/a/40560953/2344607
I have large array of objects and filtered the objects based on the userID. Here is the code below.
const filteredArr = LargeArr.Items.reduce(
async(acc, { attributes: { dob, name, picture} = { dob: null, name: null, picture: null }, userID }) => {
let pic = null;
if (picture) { pic = await getPic(picture); } // async here
acc[userID] = { name, userID, pic, dob };
return acc;
}, {});
Expected Output :
{
'1595232114269': {
name: 'Mark Status',
userID: '1595232114269',
picture: 'mark-status.jpg',
dob: '2020-08-10'
},
'48e69555d778f9b9a3a1d553b9c3b8f7dd6a3394ac82df1433b60a69c055d23d': {
name: 'Jack Thomas',
userID: '48e69555d778f9b9a3a1d553b9c3b8f7dd6a3394ac82df1433b60a69c055d23d',
picture: 'jack-thomas.jpg',
dob: '1990-12-20'
},
'48e69555d778f9b9a3a1d553b9c3b8f7dd6a3394ac82df1433b60a69c055d47p': {
name: 'Petro Huge',
userID: '48e69555d778f9b9a3a1d553b9c3b8f7dd6a3394ac82df1433b60a69c055d47p',
picture: 'petro huge.jpg',
dob: '1856-12-20'
},
'48e69555d778f9b9a3a1d553b9c3b8f7dd6a3394ac82df1433b60a69c055d55j': {
name: 'Mark Henry',
userID: '48e69555d778f9b9a3a1d553b9c3b8f7dd6a3394ac82df1433b60a69c055d55j',
picture: 'mark-henry.jpg',
dob: '2005-12-29'
}
}
I need to get picture from an api which is asynchronous, so used async await inside the reduce method. The problem here is it is always showing as Promise pending. If this was an array of object, then i can return Promise.all, but since this is object containing object how can i proceed with this inside reduce method? I need the exact same expected output.
Can somebody help me with this? Any help would be really appreciated.
To use reduce while iterating over items asynchronously, you'd have to have the accumulator which gets passed from callback to callback to be a Promise. While this is possible, it'll make things pretty difficult to read, and introduces some unnecessary syntax noise.
Use a plain for loop instead:
const filteredArr = {};
for (const item of LargeArr.Items) {
const { attributes: { dob, name, picture} = { dob: null, name: null, picture: null } } = item;
const pic = picture ? await getPic(picture) : null;
filteredArr[userID] = { name, uesrID, pic, dob };
}
If you really wanted to take the reduce route:
LargeArr.Items.reduce(
(acc, { attributes: { dob, name, picture} = { dob: null, name: null, picture: null }, userID }) => {
return acc.then(async (acc) => {
let pic = null;
if (picture) { pic = await getPic(picture); } // async here
acc[userID] = { name, userID, pic, dob };
return acc;
});
}, Promise.resolve({})
)
.then((filteredArr) => {
// do stuff with filteredArr
});
Unless the getPic calls need to be made in serial, you could consider using Promise.all instead, to iterate through the whole array at once, rather than waiting on the resolution of the prior Promise before going onto the next.
If your API can handle Promise.all:
const filteredArr = {};
await Promise.all(LargeArr.Items.map(async (item) => {
const { attributes: { dob, name, picture} = { dob: null, name: null, picture: null } } = item;
const pic = picture ? await getPic(picture) : null;
filteredArr[userID] = { name, uesrID, pic, dob };
}));
I have the following array in my javascript code:
const users = [
{
id: 1,
email: 'test#user.com',
password: 'password',
access_token: 'test_user_access_token'
},
{
id: 2,
email: 'second#user.com',
password: 'password',
access_token: 'second_user_access_token'
}
]
From this collection I want to retrieve user by email. So for example I will write:
my_function("test#user.com") it will return this one user. How can I do this?
You can use Array#find function. Pass a predicate into the function, which will return the first matched item based on that predicate.
const users = [
{
id: 1,
email: 'test#user.com',
password: 'password',
access_token: 'test_user_access_token'
},
{
id: 2,
email: 'second#user.com',
password: 'password',
access_token: 'second_user_access_token'
}
]
function findByEmail(email) {
return users.find(x => x.email === email);
}
console.log(findByEmail('test#user.com'));
That's what the .find() method is for.
const users = [
{
id: 1,
email: 'test#user.com',
password: 'password',
access_token: 'test_user_access_token'
},
{
id: 2,
email: 'second#user.com',
password: 'password',
access_token: 'second_user_access_token'
}
];
console.log(users.find(u => u.email == 'test#user.com'));
So .find() is called on the array, and receives a callback function. The callback will be invoked for each item in the array, for which you return the result of comparing the .email property to the email you're looking for.
As soon as your callback returns a true (or truthy) result, the iteration halts, and returns that object from .find(). If no is found, .find() returns undefined.
Note that this uses arrow function syntax. If you prefer, you can use traditional functions.
console.log(users.find(function(u) { return u.email == 'test#user.com' }));
There's always the good old fashioned for-loop:
const users = [{
id: 1,
email: 'test#user.com',
password: 'password',
access_token: 'test_user_access_token'
},
{
id: 2,
email: 'second#user.com',
password: 'password',
access_token: 'second_user_access_token'
}
]
function findUserByEmail(userList, desiredEmailAddress) {
for (let i = 0; i < userList.length; i++) {
var user = userList[i];
if (user.email === desiredEmailAddress) {
return user;
}
}
return null;
}
var desiredUser = findUserByEmail(users, 'second#user.com');
if (desiredUser) {
console.log('User found by email:\n');
console.log(desiredUser);
} else {
console.log('No user found with searched email address');
}