Mongoose sequence increment value not acessable - node.js

i am using mongoose module to get a pretty id but when i assign the prettyId value and use
await student.setNext("studentId");
i can't do student.save()
and i can't access student.prettyId
but it's stored in the database and it's acessable anywhere but the scope where i declare student
const { password, name, classId } = req.body;
const myClass = await Class.findOne({ prettyId: classId });
const student = new Student({
name: name,
password: await bcrypt.hash(password, 10),
class: {
id: myClass._id,
prettyId: myClass.prettyId,
name: myClass.name,
},
});
await student.setNext("studentId");
console.log(student.prettyId) // not working
await student.save() // not working

Related

I want to merge json data fetched from first api to second api data. Both api have userid as parameter in common. Please help me

app.get("/user/:id", (request, res)=>{
async function getToDoUser(){
const todoData = await fetch('https://jsonplaceholder.typicode.com/todos');
this api contains 200 entries
const response = await todoData.json();
const kuch = request.params.id;
const todoUserData = await fetch(`https://jsonplaceholder.typicode.com/users/${kuch}`);
this api will only give one entry
const userResponse = await todoUserData.json();
let responseArray = [];
var todos = {};
var target = {};
for(let i = 0; i<response.length;i++){
todos = new todoModel({
userId: response[i]["userId"],
id: response[i]["id"],
title: response[i]["title"],
completed: response[i]["completed"]
})
I have added the entries from 1st api
responseArray.push({userId: response[i]["userId"],
id: response[i]["id"],
title: response[i]["title"],
completed: response[i]["completed"]
})
}
const todoUser = new todoUserModel({
userid: userResponse["userid"],
name: userResponse["name"],
username: userResponse["username"],
email: userResponse["email"],
address: {
street: userResponse['address["street"]'],
suite: userResponse['address["suite"]'],
city: userResponse['address["city"]'],
zipcode: userResponse['addresss["zipcode"]'],
geo: {
lat:userResponse['address[geo["lat"]]'],
lng: userResponse['address[geo["lng"]]']
}
},
phone: userResponse["phone"],
website: userResponse["website"],
company: {
name: userResponse['company["nam"]'],
catchPhrase: userResponse['company["catchPhrase"]'],
bs: userResponse['company["bs"]']
},
till here 2nd api gives data and from here i want to add data from 1st api where the user id should be equal
todo: {
userId: response['0']['userid'],
userid in todo should be equal to userid in todoUser
all entries from todo with userid same as userid in todouser api
id: response['0']['id']
}
})
_.extend(target, todoUser);
// here i have merged data from todouser to new json object named target
res.send(target);
// here sending response
}
getToDoUser();
})

Not able to get the value of a custom attribute in hyperledger-fabric using cid.getAttributeValue function

Other than the 3 attributes hf.EnrollmentId, hf.type and hf.Affiliation, I've created a custom attribute named email and added it as attrs:[{name: 'email', value: rahul18#gmail.com, ecert: true}] and it was successfully added to the attribute list.
In my chaincode, i'm able to get the enrollmentId by using the following command : cid.GetAttributeValue(ctx.GetStub(), "hf.EnrollmentID") but i'm not able to get the email using the same method cid.GetAttributeValue(ctx.GetStub(), "email")
Any help would be appreciated regarding why the first one is working and the second isn't
Does getAttributeValue not support custom made attributes?
Here is an example that may be helpful. A previous stackoverflow contribution helped me with a similar situation. I don't have the link for it right now, but thanks anyway.
First of all, you state that you have added attributes successfully. Here is some code as an example which I had placed in the code file for registering users.
//create user attr array
let registerAttrs = [];
let registerAttribute = {
name: "recycler",
value: config.recycler,
ecert: true,
};
registerAttrs.push(registerAttribute);
const secret = await ca.register({
affiliation: config.affiliation,
enrollmentID: config.recycler,
role: "client",
attrs: registerAttrs,
},
adminUser
);
The contract code is able to find the value of "recycler" using the following code. Of particular importance is the getCurrentUserId() function.
async getCurrentUserId(ctx) {
let id = [];
id.push(ctx.clientIdentity.getID());
var begin = id[0].indexOf("/CN=");
var end = id[0].lastIndexOf("::/C=");
let userid = id[0].substring(begin + 4, end);
return userid;}
async getCurrentUserType(ctx) {
let userid = await this.getCurrentUserId(ctx);
// check user id; if admin, return type = admin;
// else return value set for attribute "type" in certificate;
if (userid == "admin") {
return userid;
}
return ctx.clientIdentity.getAttributeValue(userid);}
The user type returned from the getCurrentUserType function is subsequently examined further up in the contract code, as shown in the following example.
async readTheAsset(ctx, id) {
let userType = await this.getCurrentUserType(ctx);
const buffer = await ctx.stub.getState(id);
const asset = JSON.parse(buffer.toString());
asset.userType = userType;
asset.userID = ctx.clientIdentity.getID();
if (asset.userType === "recycler") {
throw new Error(`The record cannot be read by ${asset.userType} `);
}
return asset;}
I feel sure that this code should solve your issue, as there is a lot of similarity.
const updateObj = {
enrollmentID : userName,
type:'client',
affiliation:'' ,
attrs: [{name: 'email', value: email, ecert: true}, {name: 'orgId', value: orgId, ecert: true}, {name: 'userId', value: userName, ecert: true}] ,
}
const response = await identityService.update(userName, updateObj ,adminUser)
const clientUser = await provider.getUserContext(userIdentity, userName);
const reenrollment = await caClient.reenroll(clientUser,
[{
name: 'email',
optional: false
},
{
name: 'orgId',
optional: false
},
{
name: 'userId',
optional: false
}
]);

How to add an object to an array of objects in Nodejs?

I'm creating a backend for my React web application and I'm trying to subscribe a user to a match, this match is an object that have an array called "players" and when I click on the join button the username and profilePicture of the user are being dispatched to my backend. The first user info is sent perfectly but when a second user is subscribed the info of the first one is replaced for the second one.
This is my function that push the data:
const playerJoined = async (req, res) => {
const torneoId = req.params.id;
const uid = req.uid;
const profilePicture = req.profilePicture;
const username = req.username;
console.log(req.params);
try {
const torneo = await Torneo.findById(torneoId);
if (!torneo) {
return res.status(404).json({
ok: false,
msg: "Torneo no existe por ese ID",
});
}
const newPlayer = {
profilePicture: profilePicture,
username: username,
};
const nuevoTorneo = {
...req.body,
players: newPlayer,
};
const torneoActualizado = await Torneo.findByIdAndUpdate(
torneoId,
nuevoTorneo,
{
new: true,
}
);
res.json({
ok: true,
torneo: torneoActualizado,
});
} catch (error) {
console.log(error);
res.status(500).json({
ok: false,
msg: "Hable con el administrador",
});
}
};
My frontend is working well because when I added more users the array of objects shows all the players like this:
players: (2) [{…}, {…}]
But on my mongo DB shows only the last user info added like I mentioned before.
I really appreciate any help.
You seem to be replacing the players property instead of pushing into it.
const nuevoTorneo = {
...req.body,
players: newPlayer,
};
When you grab the torneo by id, you should have access to that players property already, so spread that array into your nuevoTorneo as well:
const nuevoTorneo = {
...req.body,
players: [...torneo.players, newPlayer],
};
It is because you always put your newPlayer into the "player" field of your nuevoTorneo and updated the same document. I assume you are using mongoose, You probably should just modify the "torneo" after your query and do something like this:
const torneo = await Torneo.findById(torneoId);
const newPlayer = {
profilePicture: profilePicture,
username: username,
};
torneo.nuevoTorneo.players.push(newPlayer);
await torneo.save();
Or to simply modify your code as:
const nuevoTorneo = {
...req.body,
players: [...torneo.nuevoTorneo.players,newPlayer],
};
I recommend the first method, let me know if you have any questions.

Update creates new entry instead of updating it

I have a rather simple entity model where a user has basic information. If a user also has a provider function a OneToOne relation will be created to the provider table.
My issue is that if I update a user without any provider function it works as expected. The fields which changed get updated but no new entry gets created. If the user has a provider function, all fields of the user get updated and no new entry gets created. In the table of the provider information each updated creates a new entry and the new ID gets set in the user table.
#Entity()
export class Users {
#Column('text', {primary: true})
uid: string;
#Column('text', {nullable: true})
firstName: string;
#Column('text', {nullable: true})
lastName: string;
#Column('text')
email: string;
#Column('text')
password: string;
#Column('text', {nullable: true})
role: string;
#OneToOne(type => Providers, providerData => providerData.user, {cascade: true})
#JoinColumn()
providerData: Providers;
#OneToOne(type => Clients, clientData => clientData.user, {cascade: true})
#JoinColumn()
clientData: Clients;
#Column('bytea', {nullable: true})
photo: Uint8Array;
}
Update function:
async update(uid: string, dto: UpdateUserDto): Promise<Users> {
const userToUpdate = await this.usersRepository.findOne(uid);
try {
const user = new Users();
const provider = new Providers();
const client = new Clients();
user.email = dto.email;
user.firstName = dto.firstName;
user.lastName = dto.lastName;
user.photo = dto.photo;
user.role = dto.role;
Logger.log(dto.email);
provider.licensed = dto.licensed;
provider.notes = dto.notes;
provider.paymentOptions = dto.paymentOptions;
provider.speciality = dto.speciality;
user.providerData = provider;
user.clientData = client;
const updatedUser: Users = Object.assign(user, dto);
updatedUser.uid = uid;
Logger.log('Updated User with UID: ' + userToUpdate.uid);
return await this.usersRepository.save(updatedUser);
} catch (error) {
Logger.log('Error updating user: ' + error);
}
}
What am I doing wrong or what is a better solution?
You are creating a new user instead of updating the existing one. try to add this line
const editedUser = this.usersRepository.merge(userToUpdate ,updatedUser);
and then save it
return this.usersRepository.save(editedUser);

I Want to store the resulted data in a variable for further use in sails js (mongodb)

i want to fetch the price from the database to store in order model,
here is my code
newOrder: function(req,res){
var data = req.body;
const orderNo = data.orderNo;
const user = data.user;
const business = data.business;
const inventory = data.inventory;
const price = Inventory.find({id: data.inventory}).exec(function(err,record){ return record.price});
const address = data.address;
const quantity = data.quantity;
const contactNumber = data.contactNumber;
Order.create({
orderNo: orderNo,
user: user,
business: business,
inventory: inventory,
price: price,
address: address,
quantity: quantity,
contactNumber: contactNumber
}).then(function(result){
res.ok(result);
});
},
i know it is not correct , but i don't know how to do that,
the inner query is not returning anything,
i want to store the resulted data in variable for further use.
please Help
Here you go:
newOrder: function(req,res){
var data = req.body;
const orderNo = data.orderNo;
const user = data.user;
const business = data.business;
const inventory = data.inventory;
const address = data.address;
const quantity = data.quantity;
const contactNumber = data.contactNumber;
Inventory.findOne({id: data.inventory})
.then(function(record) {
// Price is available here as record.price,
// do whatever you want with it
return Order.create({
orderNo: orderNo,
user: user,
business: business,
inventory: inventory,
price: record.price,
address: address,
quantity: quantity,
contactNumber: contactNumber
});
})
.then(function(createdOrder) {
res.ok(createdOrder);
})
.catch(function(err) {
console.log("Error ar newOrder:", err);
return res.serverError(err);
})
}
basically just fetch the inventory record first, and then you can use it in the Order query. I also swapped Inventory.find to .findOne() since it seemed like that's how you intended to use it.

Resources