Currently developing an angular app with a node.js + express backend. I have successfully requested the correct documents from mongoDB and am able to view these documents via terminal. My problem lies within getting that same data and displaying it to my html template. So far, this is what I have:
//api.js
router.get('/user/paPolicies/:id', (req, res) => {
const myquery = { _id: ObjectId(req.params.id) };
var data = req.body;
return db.collection('users').findOne(myquery, {paPolicies: 1})
.then(result => {
if(result) {
console.log(result.paPolicies)
} else {
console.log('No document matches the provided query.')
}
return result;
})
.catch(err => console.log(`Failed to find document: ${err}`))
})
//users.service.ts
getUserPaPolicies(_id: string, paPolicies: object) {
return this.http.get(`./api/user/paPolicies/${_id}`, paPolicies)
}
//user-view-portfolio.component.ts
export class UserViewPortfolioComponent implements OnInit {
id: any;
paPolicies: any = [];
constructor(private usersService: UsersService, private authService: AuthService) { }
ngOnInit(): void {
this.id = this.authService.getUserId();
console.log(this.id);
this.usersService.getUserPaPolicies(this.id, this.paPolicies).subscribe(result => {
this.paPolicies = result;
console.log(result)
});
}
}
The code I've written as seen above is able to GET the document I've requested for. However, this data can only be viewed within the terminal. An important thing to note is that paPolicies is an array and if need be, I can edit this post to add the output for console.log(result.paPolicies).
The problem(s):
The console.log within the component code does not even show any output when I view chrome dev tools console.
Apparently, if I remove this chunk of code from the component.ts:
this.usersService.getUserPaPolicies(this.id, this.paPolicies).subscribe(result => { this.paPolicies = result; console.log(result) });
the terminal would stop showing the results of my request also.
How would I modify the code to be able to display the data in my html template?
Apart from not knowing how your HTML template in the Angular frontend looks like shouldn't you send a response instead of returning the result in order to send the data to the frontend?
router.get('/user/paPolicies/:id', (req, res) => {
const myquery = { _id: ObjectId(req.params.id) };
var data = req.body;
return db.collection('users').findOne(myquery, {paPolicies: 1})
.then(result => {
if(result) {
console.log(result.paPolicies)
} else {
console.log('No document matches the provided query.')
}
// return result;
res.send(result);
})
.catch(err => console.log(`Failed to find document: ${err}`))
})
Related
I have the below route created in my application which calls another API for data:
newsr.get('/news', async (req, res) => {
var category = req.params.category;
try {
var url = 'http://newsapi.org/v2/top-headlines?country=in&category=general' + '&apiKey=36f3e29b704f41339af8439dc1228334';
const news_get = await axios.get(url)
res.status(200).json().render('category', { articles: news_get.data.articles })
// return res.status(200).json(news_get)
} catch (error) {
if (error.response) {
console.log(error)
}
}
})
The problem is, when I call the get API http://localhost:8080/news. I do not get the response from the external API. Can you please suggest what to do?
I am trying to retrieve specific user data from my Postgres DB.
This code, which retrievs all user data works:
app.get("/employees", async (req, res) => {
try {
const allEmployees = await pool.query("SELECT * FROM employees");
res.json(allEmployees.rows);
} catch (err) {
console.error(err.message);
}
});
But this code meant to retrieve one user doesn't. It returns a 404 on Postman.
app.get("/employees/:id", async (req, res) => {
try {
const { id } = req.params;
const oneEmployee = await pool.query("SELECT * FROM employees WHERE emp_id = $1", [
id
]);
res.json(oneEmployee.rows[0]);
} catch (err) {
console.error(err.message);
}
});
I don't seem to figure out what the problem is.
#AnujPancholi an update. I used the node-postgres queries documentation and changed my code as follows:
app.get("/employees/:emp_id", async (req,res) => {
const query = {
// give the query a unique name
name: 'fetch-user',
text: 'SELECT * FROM employees WHERE emp_id = $1'
}
query.values = [req.params.emp_id];
// callback
await pool.query(query, (err, response) => {
if (err) {
console.log(err.stack);
} else {
res.json(response.rows);
}
});
});
then on Postman my endpoint to a GET route
http://localhost:3000/employees/4
I did not enter any values on the params section. Thanks for pointing me in the right direction, especially on the Postman part.
I am trying to make a db call insides a loop and want to add that data into one object and then send this object to user, but I am getting only a empty object at the user end.
I already checked this one asynchronous response into a loop in javascript NodeJS
router.get('/collection', (req, res) => {
const Data = {}
Section.find({})
.then(sections => {
sections.map(section => {
let id = section._id;
Product.find({section: id})
.then(products => {
// console.log(products)
Data[section.title] = {
title: section.title,
routeName: section.title,
id,
items: products
}
console.log(Data)
})
.catch(err => {
return res.status(500).json(err)
})
})
return res.json(data)
})
.catch(err => {
return res.status(500).json(err)
})
})
I want the output to be like :-
{
food : {
items: [...]
},
vegetable: {
items: [...]
}
}
food and vegetable are keys which will be obtained from a Database Call and items in each keys are returned from a seperate call to database.
return res.json(data) is executed before any of the mapped Product-promises are resolved (also there's a typo since you're returning data instead of Data). One way to do this is to map the find-promises and to use Promise.all on the mapped array. Something like:
router.get('/collection', (req, res) => {
const Data = {}
Section.find({})
.then(sections => {
const sectionProductPromises = sections.map(section => {
let id = section._id;
return Product.find({
section: id
})
.then(products => {
Data[section.title] = {
title: section.title,
routeName: section.title,
id,
items: products
}
});
});
return Promise.all(sectionProductPromises);
})
.then(() => {
res.json(Data)
})
.catch(err => {
res.status(500).json(err)
});
});
What is the best way to chain axios / firebase promises that must be linked in a specific order and use the returns of previous promises?
I am writing a firebase function that allows me to update a user via a third-party JWT API. So I have to fulfill several promises (I use axios for that) to build the final query with a uid, a token and a refresh token.
These requests must be executed in the right order, each promise waiting for the result of the previous one to be able to execute.
recover the firebase client token to identify the user
search in a collection for the tokens (access & refresh) that were previously stored and associated with the user's uid.
Execute the "me" request on the third-party API to retrieve the user's information and update the user.
My question: What is the most correct way to chase these axios promises?
For the moment, I have managed to achieve this result, by interlocking the calls successively to properly manage the "catch" and by moving in separate functions the calls to make a little more digest the reading of the code.
/* index.js */
const userModule = require('./user');
exports.me = functions.https.onRequest( (request, response) => {
cors(request, response, () => {
let idToken = request.body.data.token;
userModule
.get(idToken)
.then((uid) => {
console.log('User found : ' + uid);
return userModule
.retrieve(uid)
.then((userTokens) => {
console.log('User tokens found : ' + userTokens.token);
return userModule
.me(userTokens.token, uid)
.then((me) => {
return me;
}).catch((error) => {
return response.status(404).json({
data : {
error : 404,
message : 'NO_USER_ON_API'
}
});
})
}).catch((error) => {
console.log(error);
return response.status(404).json({
data : {
error : 404,
message : 'NO_TOKEN_USER_FOUND'
}
});
})
})
.catch((error) => {
console.log(error);
return response.status(500).json({
data : {
error : 500,
message : 'USER_TOKEN_NO_MATCH'
}
});
})
.then((user) => {
if(user.data !== undefined)
{
return response.status(200).json({
data : {
user : user.data
}
});
}
else
{
return response.status(204).json({
data : {
user : null
}
});
}
})
});
});
/* user.js */
exports.get = (firebaseToken) {
return admin.auth().verifyIdToken(firebaseToken)
.then(function(decodedToken) {
return decodedToken.uid;
})
.catch(function(error) {
throw {
code: 500,
body: "INTERNAL_ERROR"
};
});
};
exports.retrieve = (uid) {
return admin.firestore().collection("AccessTokenCollection").doc(uid).get()
.then(function(docRef) {
return docRef.data();
})
.catch(function(error) {
throw {
code: 404,
body: "NO_USER_FOUND"
};
});
};
exports.me = (UserToken, uid) {
let params = {
params: {
},
headers: {
'Authorization': 'Bearer ' + UserToken
}
};
return axiosInstance.instance.get(url + '/users/me', params)
.then(userMe => {
return userMe;
})
.catch(errMe => {
console.log(errMe.response.status);
throw {
code: 401,
body: "EXPIRING_TOKEN"
};
});
};
Etc...
The code works as it is more a theoretical question or optimization!
const userModule = require('./user');
exports.me = functions.https.onRequest((request, response) => {
cors(request, response, async () => {
let idToken = request.body.data.token;
try {
let uid = await userModule.get(idToken);
console.log('User found : ' + uid);
let userTokens = await userModule.retrieve(uid);
console.log('User tokens found : ' + userTokens.token);
let meObj = await userModule.me(userTokens.token, uid);
} catch (error) {
console.log('error', error);
}
});
});
So, here using async-await i have removed then-catch block. await keyword will work as then and will only move forward to second call after first call has been completed. And i have made a common catch block for error handling which you can modified according to your needs
you can use promise.all and async-await instead of then and catch
I am trying to post to my backend multiple photos with their name that I get from a form.
If I have to upload just one photo it works perfectly, but it does not get the name nor upload all the photos, just the first one.
this is my code so far:
async function handleUpload() {
console.log("Upload pressed!");
console.log(photos);
let formData = new FormData();
formData.append("image", photos.files);
if (photos.length >= 1) {
try {
await fetch("/api/uploadPhoto", {
method: "POST",
data: formData
});
setPhotos([]);
} catch (err) {
console.log(err);
}
}
}
If I console.log the photos array I get this object:
I have tried mapping the format data for each element in photos trying to take the property name and saving both photos to my backend (Node + Mongoose), but I did not have success.
What would be a better approach in this situation?
Just for precision I attach also my route from the backend:
router.post("/uploadPhoto", async (req, res) => {
try {
let image = new UploadPhoto({ img: req.body });
image.img.contentType = "image/png";
image.save();
res.sendStatus(200);
} catch (err) {
res.json({ message: err });
}
});