Javascript Access an an Object in an Array - javascript

I'm fetching data from MongoDB, and the response is coming through fine, however it appears to be wrapped in array when it comes out of the User.find() function.
For example, one response is:
[{"_id":"62fe3c888e2776ef3c1a010f","username":"Drago D Trial","password":"U2FsdGVkX1867hs26KL0KitTGhWnP9tdVX6AcmI5pWE=","fullname":"Drago DaTrial","firstname":"","surname":"","email":"drago#hotmail.com","position":"QA Tester","userImage":"","locationCity":"","country":"","role":"","company":"","emailAuthorised":true,"professionalBio":"","positionRecentTitle":"","positionRecentCompany":"","companyAuthorised":"","isAdmin":false,"createdAt":"2022-08-18T13:20:08.045Z","updatedAt":"2022-08-18T13:21:02.619Z","__v":0}]
I'm accessing this through an api like this:
router.get('/inviteToJoinTeam/:token/:email', async (req, res) => {
try {
//verify the token against DB
const userToken = (req.params.token)
const indivEmailAdd = (req.params.email)
// creating user auth
try{
const userDetails = await User.find({email: indivEmailAdd})
const indivIDAdd = await userDetails (!want to access the data here and just get ID)
res.send(indivIDAdd)
}catch{
console.log('failure')
}
} catch (e) {
res.send('This isnt working');
}
});
How would you access this and just get the _id field out?

If there is only one item in the array then - simply get the id property of the first item intthe returned array
const indivIDAdd = await userDetails[0]['_id'];
or using dot notation
const indivIDAdd = await userDetails[0]._id;
if there are multiple results then map over the results and get the id from each
const ids = await userDetails.map(user => user._id);

just use response[0]._id
Ps: Response is the array coming from the database

Try projection for the same it should work
const userDetails = await User.find({ email: indivEmailAdd }, { _id : 1 })
it will return array of ObjectId. if you need to get only one object then use findOne instead of find.

According to me you have 2 solutions :
Option 1 use findOne instead of find :
const userDetails = await User.findOne({email: indivEmailAdd});
Option 2 access array / object with basic js:
const usersDetails = await User.find({email: indivEmailAdd});
const userDetails = usersDetails.at(0)._id; // or
const userDetails = usersDetails[0]['_id'];

Related

Getting Null From MongoDB

Why my Code Giving me Null
async function run() {
try {
await client.connect();
const productsCollection = client.db("inventory").collection("items");
// Get All Products
app.get('/products', async (req, res) => {
const query = {};
const cursor = productsCollection.find(query);
const products = await cursor.toArray();
res.send(products);
});
// Get Single Product
app.get('/products/:id', async (req, res) => {
const id = req.params.id;
console.log(id);
const query = {_id: ObjectId(id)};
const product = await productsCollection.findOne(query);
res.send(product);
})
}
finally {
}
}
run().catch(console.dir);
I do not understand why Null is showing?
And there is no error in giving products /id
And It doesn't even showing anything
And this error is showing in the front end console
Uncaught (in promise) SyntaxError: Unexpected end of JSON input
In mongo, you should use await on every event that is related to the database.
this is because it takes time to actually retrieve the data from the collection
and the javascript code will not wait unless you tell it to.
in your example
const cursor = productsCollection.find(query);
should be
const cursor = await productsCollection.find(query);
this is my first note
My second note is to share your frontend code and I will edit the answer if there is any thing to add

Angular: returning a value from onValue() in firebase realtime database

I would like to return the "User" object.
Got error message:
Variable 'user' is used before being assigned.ts(2454)
I tried to use async / await but I can't assign await to "return user" at the end of the code or user= await snapshot.val() because it is located on onValue() scope.
getLoggedInUser(id: string): User {
const db = getDatabase();
var user: User;
onValue(ref(db, '/users/' + id), (snapshot) => {
user = snapshot.val();
// ...
}, {
onlyOnce: true
});
return user;
}
When you call onValue you get the current value from that path in the database, and then also get all updates to that value. Since your callback may be called multiple times, there is no way to return a single value.
If you want to just get the value once and return it, you'll want to use get instead of onValue. Then you can also use async/await.
async getLoggedInUser(id: string): Promise<User> {
const db = getDatabase();
var user: User;
const snapshot = await get(ref(db, '/users/' + id))
user = snapshot.val();
return user;
}
I am actually having a similar issue, although I try to fetch data with paging logic.
We do have thousands of records and to render them nicely (10 - 25 per page) would be the best option anyhow.
const dbRef = query(ref(database, folder), orderByChild(field), startAt(start), limitToLast(limit))
return onValue(dbRef, (snapshot) => {
const values = Object.values(snapshot.val());
return {data: values, total: values.length, page: page}
})
I can see the values inside the onValue, but it seems not to return the value at all. I'm not sure where to go here, the documentation on that is not completely clear to me (a beginner as a developer).

Mongoose - find() not returning anything when no parameters are passed, but returns data when parameters are passed

I have the following model in teamMembers.js:
const { Schema, model } = require('mongoose');
const teamMembersSchema = new Schema({
uid: String,
name: String,
hours: Number
})
const TeamMembers = model('teamMembers', TeamMembersSchema);
module.exports = TeamMembers;
I've created the following endpoints in teamMemberRoute.js:
const TeamMembers = require('./models/teamMembers');
module.exports = (app) => {
app.get('/api/pods/teamMembers/:uid', async (req, res) => {
let teamMember = await TeamMembers.find( {'uid': req.params.uid } );
return res.status(200).send(teamMember);
});
app.get('/api/pods/teamMembers', async (req, res) => {
let teamMembers = await TeamMembers.find();
return res.status(200).send(teamMembers);
});
}
The first endpoint (/api/pods/teamMembers/:uid) works just fine - when I pass a uid it returns documents specific to that uid in the TeamMember collection.
The second endpoint should return all documents from the TeamMember collection since no parameters are passed. However, when the request is executed, only [] is returned. We know for a fact that documents exist in the TeamMember collection, since the first endpoint returns data from that collection based on the uid parameter that is passed.
I'm stumped on this. Any ideas? I don't think there is anything wrong with my model since I am able to execute the first endpoint with no issues.
Express executes code from top to button, and that is the reason for this issue. It will match your first endpoint and assume that uid is null. Just change the order of defined endpoints, like this:
module.exports = (app) => {
app.get('/api/pods/teamMembers', async (req, res) => {
let teamMembers = await TeamMembers.find();
return res.status(200).send(teamMembers);
});
app.get('/api/pods/teamMembers/:uid', async (req, res) => {
let teamMember = await TeamMembers.find( {'uid': req.params.uid } );
return res.status(200).send(teamMember);
});
}

Use GET to return records based on nested fields

I am trying to retrieve records based on a value in a mongo dataset that is in a nested object.
data is an object and documentId is a field within it and I want to retrieve just the objects within data that have the documentId of "5da713edf0a1645ae95b11oo"
I tried this code
const res = await axios.get('/api/card',{
params:{
data:documentId: "5da713edf0a1645ae95b11oo"
}
});
but it just returns all the records
Try one of these:
const res = await axios.get('/api/card',{
params:{
documentId: "5da713edf0a1645ae95b11oo"
}
});
This would be a GET request to /api/card?documentId=5da713edf0a1645ae95b11oo
or
const res = await axios.get('/api/card',{
params:{
data: {
documentId: "5da713edf0a1645ae95b11oo"
}
}
});
This would be a GET request to something like /api/card?data=%7B%22documentId%22%3A%225da713edf0a1645ae95b11oo%22%7D
...where %7B%22documentId%22%3A%225da713edf0a1645ae95b11oo%22%7D is URL encoded version of {"documentId":"5da713edf0a1645ae95b11oo"}
according to the documentations it says that we can not do what you have done.
axios.get('/api/card')
.then((res) => {
const data = res.data.id;
//handle your response here.
//can write your logic to retrieve your specific data
});
for further in formations refer this doc
I'm going to assume the data you're receiving on the response is an array of objects. You can filter through it. You're going to have to loop through the data though.
const res = await axios.get('/api/card')
const filteredData = res.data.filter((item) => item.documentId === '5da713edf0a1645ae95b11oo')
You can try this:
data_get() {
axios.get('/api/card')
.then((res) => {
this.setState({
documentId: res.data.id, //5da713edf0a1645ae95b11oo
});
});
}

How to get data from different collections in firebase from react?

So i have 2 collections
1 collection is 'users'. There i have documents (objects) with property 'profile', that contains string. It's id of profile, that is stored in other collection 'roles' as document.
So i'm trying to get this data, but without success. Is there exist join method or something like that? Or i must use promise for getting data from collection roles, and then assign it with agent?
async componentDidMount() {
firebase
.firestore()
.collection('users')
.orderBy('lastName')
.onSnapshot(async snapshot => {
let changes = snapshot.docChanges()
const agents = this.state.agents
for (const change of changes) {
if (change.type === 'added') {
const agent = {
id: change.doc.id,
...change.doc.data()
}
await firebase
.firestore()
.collection('roles')
.doc(change.doc.data().profile).get().then( response => {
//when i get response i want to set for my object from above this val
agent['profile'] = response.data().profile
//after that i want to push my 'agent' object to array of 'agents'
agents.push(agent)
console.log(agent)
}
)
}
}
this.setState({
isLoading: false,
agents: agents
})
})
}
To do async operation on array of objects you can use promise.all, i have given a example below that is similar to your use case where multiple async operation has to be done
const all_past_deals = await Promise.all(past_deals.map(async (item, index) => {
const user = await Users.get_user_info(item.uid);
const dealDetails = await Deals.get_deal_by_ids(user.accepted_requests || []);
const test = await Users.get_user_info(dealDetails[0].uid);
return test
}))
}
This way you can get data from once api call and make other api call with the obtained data

Categories