Store data from new class instance in an array - javascript

I want to create 4 new users,
let JonSnow = new User({ id: 1, name: 'Jon Snow', status: Status.user });
let AryaStark = new User({ id: 2, name: 'Arya Star', status: Status.user });
let SansaStark = new User({ id: 3, name: 'Sansa Stark', status: Status.user });
let JoffreyBaretheon = new User({ id: 4, name: 'Joffrey Baretheon', status: Status.user });
In my User class I have a allUser function,
allUsers() {
let users: IUser[] = [];
let user: IUser = {
id: this.id,
name: this.name,
status: this.status
}
users.push(user);
users.forEach((user) => console.log(user));
return users;
}
If I call the the function like so,
JonSnow.allUsers();
AryaStark.allUsers();
SansaStark.allUsers();
JoffreyBaretheon.allUsers();
It calls the allUsers function 4 times, as expected.
How would I store all 4 new users into one array? So I would only need to call the function once to show all users?

You can have a module/namespace variable (don't export it so it won't be accessible from outside), like so:
let users: IUser[] = [
new User({ id: 1, name: 'Jon Snow', status: Status.user }),
new User({ id: 2, name: 'Arya Star', status: Status.user }),
new User({ id: 3, name: 'Sansa Stark', status: Status.user }),
new User({ id: 4, name: 'Joffrey Baretheon', status: Status.user })
]
and then you have a simple method:
allUsers(): IUser[] {
return users.slice(0);
}
Notice that I cloned the users array so that who ever gets a reference to it won't be able to change this inner array, but it's not a must.
But there's no real need to have this method in all classes, you can make it static.
But you can also then make this array a static member of the User class, so:
class User {
private static users: IUser[] = [];
constructor() {
User.users.push(this);
}
static allUsers(): IUser[] {
return User.users.slice(0);
}
}
The you can get all users: User.allUsers().

It seems like you are just trying to convert a bunch of User instances into a single array of IUser objects.
What I would do is provide a User class method that returns an IUser object:
public toIUser():IUser {
return {
id: this.id,
name: this.name,
status: this.status
}
}
Then simply map your instances using that function:
let allUsers = [JonSnow, AryaStark, SansaStark, JoffreyBaretheon].map(user => user.toIUser());
console.log("all users:", allUsers);
Playground example here.
PS: I would avoid using static variables as your solution.

Declare static User variable as an array:
User.users = []
In User constructor add the current object to the array:
User.users.push(this)
Then in allUsers return the array:
allUsers() {
return User.users
}

Related

Javascript array becoming null after second run

'''
const users = []
const addUser = ({ id, username, room }) => {
// Clean the data
username = username.trim().toLowerCase()
room = room.trim().toLowerCase()
// Validate the data
if (!username || !room) {
return {
error: 'Username and room are required'
}
}
// Check for existing user
const existingUser = users.find((user) => {
return user.username === username || user.room === room
})
// Validate username
if (existingUser) {
return {
error: 'Username already exists!'
}
}
// Store user
const user = { id, username, room }
users.push(user)
return { user }
}
addUser({
id: 03,
username: 'rohan',
room: 'playground'
})
console.log(users)
'''
If I run this in console the output is [ { id: 3, username: 'rohan', room: 'playground' } ]
But again if i just comment out the call and print the array. It showing empty.
'''
//addUser({
// id: 03,
// username: 'rohan',
// room: 'playground'
//})
console.log(users)
'''
From first run the value stored in object so It must be in the users array forever. Why this is empty if I dnt add value?
The following demo features 2 separate objects (userObjA, and userObjB), an arrow function called addUser(...user) which can accept any number of given objects (because of the spread operator: ... magic) then returns said objects wrapped in an array of objects (users).
Note: no const were hurt during the demonstration -- healthy free range let are leveraged for painless declarations and assignments.
Demo
let userObjA = {
id: 3,
name: 'Rohan',
room: 'Suite 42'
};
let userObjB = {
id: 4,
name: 'Dell',
room: 'Single 601'
};
const addUser = (...user) => {
let users = [];
users.push(user);
return users.flat();
};
console.log(addUser(userObjA, userObjB));

Nothing assign into array element in nodejs app

I have a problem in my express project that I can't resolve since a day. I can't push some data into array element. Let me demonstrate my code and data.
Here is my result data which coming from mongodb:
result = {
name: 'Workflow',
steps:[
{ name: 'First Step',
assignee: '2cb56eadab3fbdc46dcb896e2ec68f33'
},
{
name: 'Second Step',
assignee: '1h374jab3fbdc46wer896e2ec687as'
}
],
__v: 0
}
Here is my code block:
var save = function(data, next) {
return new Promise(function(resolve) {
if (_.isEmpty(data._id)) {
Workflow.create(data, function (err, result) {
if (err) return next(err);
result.steps.forEach(function(step) {
step.detail = {
fullName: 'blablabla',
avatar: 'blablabla'
}
});
resolve(result);
});
}
}
}
After running code block my expectation is:
result = {
name: 'Workflow',
steps:[
{ name: 'First Step',
assignee: '2cb56eadab3fbdc46dcb896e2ec68f33',
detail: {
fullname: 'blablabla',
avatar: 'blablabla'
}
},
{
name: 'Second Step',
assignee: '1h374jab3fbdc46wer896e2ec687as',
detail: {
fullname: 'blablabla',
avatar: 'blablabla'
}
}
],
__v: 0
}
I can't get my expectation from result data and can't understand why detail is not assign steps array elements?
You can't directly modify the objects that MongoDB gives you, they're frozen.
You can copy the object and assign to the copy:
const copy = {...result, steps: result.steps.map(step => {
const stepCopy = {...step};
stepCopy.detail =
fullName: 'blablabla',
avatar: 'blablabla'
};
return stepCopy;
})};
resolve(copy);
That can actually be written more concisely, but it starts getting hard to read:
const copy = {...result, steps: result.steps.map(step => (
{...step, detail: {
fullName: 'blablabla',
avatar: 'blablabla'
}}
)};
resolve(copy);
Or, since I notice you're using ES5 syntax (but presumably with polyfills):
var copy = Object.assign({}, result);
copy.steps = copy.steps.map(function(step) {
var stepCopy = Object.assing({}, step);
stepCopy.detail = {
fullName: 'blablabla',
avatar: 'blablabla'
};
return stepCopy
)};
resolve(copy);
You'll need a polyfill for Object.assign (or I see Underscore/Lodash in your code, you can use _.extend instead, you literally just replace Object.assign with _.extend in the above).
You can do it in another way. Add detail object in the model itself. Set default value in the model definition.

Many() relationships with same model in redux-orm

What I need is to model Member have a list of followers and followings.
You define the relation the same way you'd define it for non-self-referencing many-to-many.
class Follower extends Model {
static modelName = 'Follower';
static fields = {
id: attr(),
name: attr(),
followers: many('Follower','following')
};
}
const orm = new ORM();
orm.register(Follower);
const session = orm.session(orm.getEmptyState());
session.Follower.create({id: 1, name: 'f1'});
session.Follower.create({id: 2, name: 'f2'});
session.Follower.create({id: 3, name: 'f3', followers: [1,2]});
// returns ['f1', 'f2']
const f3Followers = session.Follower.withId(3).followers.toRefArray().map(f=>f.name);
// returns ['f3']
const f1Following = session.Follower.withId(1)!.following.toRefArray().map(f=>f.name);

Throwing Nan message for a property of JSON

I have developed an Angular4 appln that calls a nodeExpressJS server to fetch JSON data and also adds data to the JSON object. The following is the onSubmit function of the addemployeeform.
onSubmit(formValue: any) {
console.log("Form Value = " + JSON.stringify(formValue, null, 4));
let newEmployee: Emp;
let last: any;
this._employeeService.lastEmployeeID().subscribe((last: any) => last = last,
err => console.log(err));
newEmployee = {
//id: employeeCount + 1,
id: last + 1,
name: formValue.name,
manufacturer: formValue.manufacturer,
type: formValue.type,
batchno: formValue.batchno,
expdate: formValue.expdate,
price: formValue.price
};
// console.log(newEmployee.id );
let temp = this._employeeService.addEmployee(newEmployee).subscribe(err =>
console.log(err));
this.router.navigate(['employees']);
}
But then it isn't pushing the id property to the JSON for newEmployee.
{id: 1, name: "Paracetamol", manufacturer: "Ranbaxy", type: "Tablet", batchno …}
{id: 2, name: "Sinarest", manufacturer: "GSK", type: "Tablet", batchno: …}
{id: 3, name: "Viagra", manufacturer: "Pfizer", type: "Capsule", batchno: …}
{name: "Aspirine", manufacturer: "Aspirine", type: "Syrup", batchno: "03/46", expdate: "03/04/2023", …}
newEmployee is Aspirine.
And on uncommenting console.log(newEmployee.id ); line of code
I get a Nan error
First, shouldn't last be defined as a number and not any?
Second, and more importantly, the lastEmployeeId call is most likely asynchronous, meaning it will not have completed before the next line of code is complete. You need to add all of the code that executes after that operation within the subscribe.
this._employeeService.lastEmployeeID().subscribe(
(last: any) => {
last = last;
newEmployee = {
//id: employeeCount + 1,
id: last + 1,
name: formValue.name,
manufacturer: formValue.manufacturer,
type: formValue.type,
batchno: formValue.batchno,
expdate: formValue.expdate,
price: formValue.price
};
// console.log(newEmployee.id );
let temp = this._employeeService.addEmployee(newEmployee).subscribe(
employee => {
console.log(employee);
this.router.navigate(['employees']);
},
err => console.log(err)
);
And with that much code in the first function passed to your subscribe, you may want to instead make it it's own function:
this._employeeService.lastEmployeeID().subscribe(
(last: number) => this.processEmployeeId(last),
err => console.log(err));
processEmployeeId(last: number) {
// Your code here.
}
if last is supposed to be a number type then state so:
let last: number;
If you're going to use typescript - you might as well use it to your advantage.

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