Output data from object array - javascript

I want to output list of user from object. This object is array and when I don't use specific number of user I get invalid data. But when I put number for user in object I get information that I need. My question is, why my code does't work properly and how to output all user?
// Give Users needed types
type typeUsers = { name: string; age?: number };
// List of users
const Users: typeUsers[] = [
{
name: "John",
age: 21,
},
{
name: "Max",
},
];
function UserFunc(Users) {
// If user has age output this
if ("age" in Users) {
console.log(`Name: ${Users.name}, Age: ${Users.age}`);
} else {
console.log(`Name: ${Users.name}`);
}
}
UserFunc(Users);
But also its work when I change last string to UserFunc(Users[number])

First, it's common in javascript to write the variable names in camelCase.
Second, Users is an array of object, so you need to iterate over, to log each object inside.
// Give Users needed types
type typeUsers = { name: string; age?: number };
// List of users
const users: typeUsers[] = [
{
name: "John",
age: 21,
},
{
name: "Max",
},
];
function userFunc(users: typeUsers[]) {
// loop throw users array with `forEach` method
users.forEach(user => {
// If user has age output this
if ("age" in user) {
console.log(`Name: ${user.name}, Age: ${user.age}`);
} else {
console.log(`Name: ${user.name}`);
}
})
}
userFunc(users);
This is a working exmaple

if ("age" in Users) only works with objects, not with arrays. you can loop over the array like that:
// Give Users needed types
type typeUsers = { name: string; age?: number };
// List of users
const Users: typeUsers[] = [
{
name: "John",
age: 21,
},
{
name: "Max",
},
];
function UserFunc(Users: any) {
// If user has age output this
Users.forEach((User: any)=>{
if ("age" in User) {
console.log(`Name: ${User.name}, Age: ${User.age}`);
} else {
console.log(`Name: ${User.name}`);
}
})
}
UserFunc(Users);

Users is an array. So in order to access an element in array you have to do Users[0].name or Users[1].name.
Or, if you want to output all the data, wrap your if else structure in an Array.forEach() like so:
// Give Users needed types
type typeUsers = { name: string; age?: number };
// List of users
const Users: typeUsers[] = [
{
name: "John",
age: 21
},
{
name: "Max"
}
];
function UserFunc(Users: typeUsers[]) {
// If user has age output this
Users.forEach((user) => {
if ("age" in user) {
console.log(`Name: ${user.name}, Age: ${user.age}`);
} else {
console.log(`Name: ${user.name}`);
}
});
}
UserFunc(Users);

The problem is that you are checking for the User property age directly from the array. As others have pointed out, you need to loop through the array to access each of the User object where the check for property age will be valid.
// Give Users needed types
type typeUsers = { name: string; age?: number };
// List of users
const Users: typeUsers[] = [
{
name: "John",
age: 21,
},
{
name: "Max",
},
];
function UserFunc(Users) {
// If user has age output this
for (const user of Users) {
if ("age" in user) {
console.log(`Name: ${user.name}, Age: ${user.age}`);
} else {
console.log(`Name: ${user.name}`);
}
}
}
UserFunc(Users);

Related

How to remove an object from an array if it has the letter a?

I need to make a function that receives 2 parameters, the first one is an array of a list of users that must contain first name, last name and phone numbers, at least 3 of those users must start with the letter "a", the second parameter is a callback. You must process the array and delete all the users whose name starts with the letter "a". Then send the new processed array to the callback. The callback must show in console, the list of all the names, concatenating first and last name.
const users =
[{
name: 'Diego',
lastname: 'Garcia',
phone: '12343'
},
{
name: 'Camilo',
lastname: 'Garcia',
phone: '12343'
}, {
name: 'ana',
lastname: 'Rodriguez',
phone: '02343'
}, {
name: 'anastasia',
lastname: 'Zapata',
phone: '42343'
}, {
name: 'alejandra',
lastname: 'Perez',
phone: '52343'
}];
const operation2 = (list) => {
let x = [];
let callback = {};
callback = list.find(element => element.name.charAt(0) == 'a');
let l = list.indexOf(callback)
let g = list[l];
console.log(g)
if (callback) {
x = list.splice(l, 1)
} return list
}
console.log(operation2(users))
The code that I made does not work, it is not eliminating all the names that begin with "a", it only eliminates the first object of the array.
Array.find only finds the first match, you should probably filter out the elements you don't want:
const result = list.filter(element => element.name.charAt(0) !== 'a');
const users =
[{
name: 'Diego',
lastname: 'Garcia',
phone: '12343'
},
{
name: 'Camilo',
lastname: 'Garcia',
phone: '12343'
}, {
name: 'ana',
lastname: 'Rodriguez',
phone: '02343'
}, {
name: 'anastasia',
lastname: 'Zapata',
phone: '42343'
}, {
name: 'alejandra',
lastname: 'Perez',
phone: '52343'
}];
function func(list, callback) {
let users = list.filter(u => !u.name.toLowerCase().startsWith('a'));
callback(users)
}
func(users, (users) => {
console.log(users)
})

Sequelize magic method returning null

Just a bit confused as to why this magic method is returning null. It's probably very simple, but I'm using methods I wouldn't normally (bulkingCreating) and can't currently see it.
Association: Country.hasOne(Capital, { foreignKey: 'countryId' });
Populating dummy data:
const countries = await Country.bulkCreate([
{ name: 'England' },
{ name: 'Spain' },
{ name: 'France' },
{ name: 'Canada' }
]);
const capitals = await Capital.bulkCreate([
{ name: 'London' },
{ name: 'Madrid'},
{ name: 'Paris' },
{ name: 'Ottawa' }
]);
countries.forEach((country, index) => {
country.setCapital(capitals[index]);
});
const country = await Country.findOne({where: {name: 'Spain'}});
console.log(country.name, Object.keys(country.__proto__)); // Spain / magic methods
const capital = await country.getCapital();
console.log(capital); // null
The table:
Am I wrong in thinking country.getCapital() should return the relevant entry?
As you might guess setCapital should be an async function because it makes changes in DB so you need to use for instead of forEach method that does not support async callbacks:
let index = 0;
for (const country of countries) {
await country.setCapital(capitals[index]);
index += 1;
}
It would be better to create countries one by one and create capitals for them not relying on the same indexes of both collections (DB might return created records in a different order).
If you are using Sequelize 5.14+, you can do this in 1 bulkCreate using include option.
const countries = await Country.bulkCreate([
{
name: 'England',
Capital: { // This keyname should be matching with model name.
name: 'London'
}
},
{
name: 'Spain',
Capital: {
name: 'Madrid'
}
},
...
],
{
include: Capital,
returning: true // If Postgres, add this if you want the created object to be returned.
}
);

Retrieving data from user input and save it to mongoose model

This is my model shema:
const DemoSchema = new Schema({
rowOne: {
colOne: {
one: {
name: String,
qty: Number,
},
two: {
name: String,
qty: Number,
},
three: {
name: String,
qty: Number,
},
},
},
rowTwo: {
colOne: {
one: {
name: String,
qty: Number,
},
two: {
name: String,
qty: Number,
},
three: {
name: String,
qty: Number,
},
},
},
});
When I do this it saves data to my model:
const product = await new Regal({
rowOne: { colOne: { two: { name: productName, qty: productQty } } },
});
product.save();
My question is, how can I replace rowOne, colOne and two with user input?
I tried this:
const row = req.body.rows // this must be rowOne or rowTwo
const column = req.body.column // colOne or other (colOne to colNine)
const col = req.body.col // one, two or three
const productName = req.body.name
const productQty = req.body.qty
Attempt 1:
const product = await new Regal({ `${row}`: { `${column}`: { `${col}`: { name: productName, qty: productQty }}}});
'Error --> Property Assignment expected.'
Atempt 2:
const product = await new Regal(`{${row}: { ${column}: { ${col}: { name: ${productName}, qty: ${productQty} } } } }`);
'Error --> Parameter "obj" to Document() must be an object, got {rowOne: { colOne: { one: { name: Milk, količina: 250 } } } }'
You can use variables as keys of objects using square brackets.
let user = 'username';
let newObj = { [user]:'saloni' }
this will create an object like {username:saloni}.
This way you can replace rowOne, colOne, and two with user input by storing them in a variable and then use it.

JavaScript (ReactJS) comparing two Objects

I have an object with users:
const data = [
{
name: "John",
lastName: "Doe",
email: "stefa#gmail.com",
password: "123",
following: [{ id: "113"}, { id: "111" } }],
id: "112",
},
{
name: "Jane",
lastName: "Doe",
email: "dusica#gmail.com",
password: "123",
following: [{ id: "112" }],
id: "113",
},
{
name: "Mark",
lastName: "Twain",
email: "marko#gmail.com",
password: "123",
following: [],
id: "111",
},
];
As you can see all users have an array named "following", and that array contains id's of users which the user follows. I want to access that array "following" to find out which users are not followed. Let's say that we want to check the "following" array of the first user John Doe with id="112".
const followers = [];
let suggestions = null;
props.users.forEach((user) => {
if (user.id === '112') {
user.following.forEach((item) => {
followers.push(item);
});
}
});
followers.map((item) => {
suggestions = props.users.map((user) => {
if (user.id !== item.id && user.id !== '112) {
console.log(item.id);
return <div>something</div>;
}
});
});
I tried something like this, but the result is not what i expected to be. As i said, i want to return users that are not followed and render them because i want them to be visible so the user can follow them. I hope that i was understandable enough. Thanks.
It's a negative comparison.
So you want to filter out all users that a user IS following.
You can loop through each user and compare it against the following array. If the following array contains the user then don't show it.
const notFollowing = allUsers.filter(user =>
!currentUser.following.some(({ id }) => id === user.id)
);

In JavaScript, how can I store an array of object value into string variable?

I have this object with the following data that I need to store in a variable:
user: [
{
firstname: 'John',
lastname: 'Doe',
roles: [
{
roleId: 18,
displayText: 'accountant',
description: 'accountant'
}
]
}
]
I am looping through this object as such:
let selectedRole = user.roles.map((role, index) => {
return role.displayText
})
selectedRole returns me the following output: ["accountant"]
For example:
John Doe has only 1 role assigned to him -> account
Sam Williams has 3 roles assigned -> program manager, account, admin
let's say if I click on Sam William's details then I want to see all the roles that I assigned to him in not comma separated but in the following layout:
Role 1: program manager
Role 2: account
Role 3: admin
If you want to get all elements of the array as a delimited string, you can use Array.prototype.join: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join
let selectedRoles = user.roles.map((role, index) => {
return role.displayText
});
let rolesString = selectedRoles.join();
If selectedRoles is ['accountant', 'admin'] then the value of rolesString will be accountant, admin. The parameter of join is optional, but its value is the delimiter (comma is default).
EDIT
So if you don't want them as one string, but instead you want to display them individually on the screen. How are you displaying them? Are you using Angular or some other library/framework, or are you using plain JavaScript?
If you're using Angular, for example, you'll use its mechanisms for looping over a collection. So:
<ul *ngFor="let role of selectedRoles; let idx = index">
<li>Role {{idx}}: {{role}}</li>
</ul>
If you don't need an array, but just the string, then don't use .map:
const user = [
{
firstname: 'John',
lastname: 'Doe',
roles: [
{
roleId: 18,
displayText: 'accountant',
description: 'accountant'
}
]
}
];
const selectedRole = user[0].roles[0].displayText;
console.log(selectedRole);
If you want to join all roles into a string, use .join by whatever delimiter you want:
const user = [
{
firstname: 'John',
lastname: 'Doe',
roles: [
{
roleId: 18,
displayText: 'accountant',
description: 'accountant'
},
{
roleId: 20,
displayText: 'somethingElse',
description: 'somethingElse'
}
]
}
];
const selectedRole = user[0].roles.map((r, i) => `Role ${i + 1}: ${r.displayText}`).join('\n');
console.log(selectedRole);

Categories

Resources