My problem is how can I bring my data structure into the query? I want to be able to search everything via one query. How can I implement this?
I tried to enter the query so => ?basicData.tasks.title=Fleetmanagement. With it I can find all the data that fleet management has in it. But now I want to search with two titles.
Example:
?basicData.tasks.title=Fleetmanagement&basicData.tasks.title=OCPP Backend
But it doesn't work. How can i implement that right?
This is my data structure:
"basicData": {
"tasks":[
{"title": "Fleetmanagement"},
{"title": "OCPP Backend"}
]
}
My Code:
export const allCompanyData = (req: Request, res: Response) => {
if (req.query) {
Company.find(req.query).then(docs => {
logger.info(`Query works ${req.query}`);
res.json({
query: req.query
})
res.status(200).json(docs);
}).catch(err => {
logger.error(`Error ${err}`);
res.status(400).json(`Error ${err}`)
})
} else {
Company.find()
.then((items: any) => {
logger.info("Successful finding");
res.status(200).json(items);
})
.catch((err: any) => {
logger.error(`Error ${err}`);
res.status(400).json(`Error ${err}`);
});
}
};
You append [] to the param name on the client side to indicate that you are providing an array:
?basicData.tasks.title[]=Fleetmanagement&basicData.tasks.title[]=OCPP%20Backend
Then req.query will be:
{ 'basicData.tasks.title': ['Fleetmanagement', 'OCPP Backend'] }
Related
Good morning everyone!
I'm developing an application with Node.js and Angular, and I'm getting a little stuck lately.
I need to append a custom key -> value to an existing query result collection.
This is the function I have:
exports.findAll = (req, res) => {
Project.findAll({
include: [{
all: true,
include: [{
all: true
}]
}]
})
.then(data => {
data.forEach(
(project) => {
// <-------- HERE GOES THE APPEND
}
);
res.send(data);
})
.catch(err => {
res.status(500).send({
message: err.message || "Error retrieving projects"
});
});
};
Description:
After getting the result from the model query, I iterate over each result (aka Project).
Then, what I need to do is append a key -> value pair to that very Project.
By now, I'd like to do something like this:
exports.findAll = (req, res) => {
Project.findAll({
include: [{
all: true,
include: [{
all: true
}]
}]
})
.then(data => {
data.forEach(
(project) => {
project.cat = "miaw";
}
);
res.send(data);
})
.catch(err => {
res.status(500).send({
message: err.message || "Error retrieving projects"
});
});
};
This try hasn't made any changes in my JSON collection, and I don't know how to accomplish it neither.
Could someone give me some help?
I've searched everywhere but couldn't find anything useful.
Thank you so much!
You just need to get plain objects from model instances and then you can add whatever you need to:
const projects = data.map(x => x.get({ plain: true }))
projects.forEach(
(project) => {
project.cat = "miaw";
}
);
res.send(projects);
I'm trying to query from a table where the teacherId is equal to the teacherId of the person that logs in but I can't pass that teacherId from the front-end to the back-end.
This is the back end
app.get("/api/get", async(req,res) => {
const teacherId = req.body.teacherId
connection.query(
"SELECT class FROM homework WHERE teacherID = ?",
[teacherId],
(err, result) => {
if (result){
res.send({ message: result })
} else{
console.log(err)
}
}
)
})
This is the front end
useEffect(() => {
Axios.get("http://localhost:1337/api/get", {
teacherId: teacherId
}).then((response) => {
if(response){
setDisplayHomework(response.data.message)
} else{
console.log("error")
}
})
})
const teacherId = localStorage.getItem("teacherId")
I think the problem lies where it says teacherId: teacherId but I don't know why.
You need to use
Axios.get("http://localhost:1337/api/get", {
params: { teacherId }
});
and use req.query.teacherId to read it
If you see the Axios.get signature it is
axios.get(url[, config])
in contrast to
axios.post(url[, data[, config]])
which passes the data as the second argument.
That is because the body in GET requests is not used by the servers. Read HTTP GET with request body for more on this.
Usually you do not send a body with a get request. Put the teacher id into the url. Then this is called path variable.
app.use('/teacher/:teacherId', function(req, res, next) {
console.log(req.params.teacherId);
next();
})
Get requests don't have request bodies unlike post requests, as such the Axios.get function shouldn't have a second parameter for the body. Instead pass your parameters as a url, like this:
useEffect(() => {
Axios.get("http://localhost:1337/api/get?teacherId="+teacherId).then((response) => {
if(response){
setDisplayHomework(response.data.message)
} else{
console.log("error")
}
})
})
Then in your backend code use req.params to access the get request url parameters:
app.get("/api/get", async(req,res) => {
const teacherId = req.params.teacherId
connection.query(
"SELECT class FROM homework WHERE teacherID = ?",
[teacherId],
(err, result) => {
if (result){
res.send({ message: result })
} else{
console.log(err)
}
}
)
})
I have two collections, posts and tags. posts contains a postId and other metadata, including tags. This is what a post would look like:
{
"tags": [
"tag1",
"tag2",
...
],
"message": "test message"
...
}
This returns the post above, with a postId.
Using Axios, I receive this data in my function. I want to take each tag, put them in the tags collection along with the postId associated with it.
An example of the tags collection:
tags: {
tag1: {
"postId1",
"postId2"
},
tag2: {
"postId1",
"postId3"
}
}
I'm stuck adding the tags to its own collection in Firebase, and I've tried using forEach tag and updating the tags collection one by one, but that hasn't been working for me.
The code I currently have:
db.collection("posts")
.add(oneNewPost)
.then((doc) => {
// add the post body to the "posts" collection
const resPost = oneNewPost;
resPost.postId = doc.id;
res.json(resPost);
})
.then(() => {
// DOESNT WORK HERE --> overwrites changes in firebase "tags" collection
let batch = db.batch();
resPost.tags.forEach((doc) => {
const docRef = db.collection("tags").doc(doc);
batch.update(docRef, { postId: resPost.postId }, { merge: true });
});
batch.commit().then(() => {
return res.json({...resPost});
});
})
.catch((err) => {
res.status(500).json({ error: "something went wrong" });
console.error(err);
});
Please let me know if anything is unclear!
I got it to work using the following code:
.then((resPost) => {
// add postId's to tag collection here
let batch = db.batch();
resPost.tags.forEach((doc) => {
const docRef = db.doc(`/tags/${doc}`);
batch.update(
docRef,
{ postId: admin.firestore.FieldValue.arrayUnion(resPost.postId) },
{ merge: true }
);
});
batch
.commit()
.then(() => {
return res.json({ ...resPost });
})
.catch((err) => {
console.error(err);
return res.status(500).json({ error: err.code });
});
})
Basically, you need to do a batch update, but also for a specific FieldlValue for each postId.
I'm working on a VueJS web app, in which I need to query a db of peoples names based off user input.
In my server.js file I have my API endpoint which I want to query and have it hosted on localhost:4000
//Staff
app.get('/staff', (req,res) => {
connection.query(SELECT_CERTAIN_STAFF, (error,results) => {
if(error){
return res.send(error)
}
else {
console.log('Selected STAFF from People')
return res.json({
data: results
})
}
})
})
In my Search.vue this is my search method
//Data
data(){
return {
input: '',
errors: ''
}
},
//Methods
methods:{
search(keyboard){
console.log(this.input)
axios.get('http://localhost:4000/staff?username='+this.input)
.then(response => {
console.log(JSON.stringify(response.data.data))
})
.catch(error => {
console.log(error)
this.errors = error
})
console.log(keyboard.value)
}
},
I added console.log(this.input) + console.log(keyboard.value) to test the correct input is being taken from the user, which it is
In my response, the console.log(JSON.stringify(response.data.data)) is just returning the data in the endpoint /staff, and is not filtering any of the data based on user input.
Anyone have any idea why it's doing this/ different approach? Have I set up the API endpoints correctly?
Thanks
When building a component that contains 3D print information named a fabmoment, I succeeded using the $route.params filling an author-object and a fabmoment-object with information, like so:
<script>
import SingleSummarized from './SingleSummarized'
// import Comments from '#/components/Comments/Multiple'
export default {
name: 'Single',
data () {
return {
author: null,
fabmoment: null,
tempLicenseID: null,
license: null
}
},
created () {
this.$http.get(`/users/${this.$route.params.author_id}`)
.then(request => { this.author = request.data })
.catch(() => { alert('Something went wrong when trying to retrieve this user!') })
this.$http.get(`/users/${this.$route.params.author_id}/fabmoments/${this.$route.params.fabmoment_id}`)
.then(request => { this.fabmoment = request.data })
.catch(() => { alert('Something went wrong when trying to retrieve the fabmoment attribute data!') })
this.$http.get(`/licenses/${this.fabmoment.license_id`)
.then(request => { this.license = request.data })
.catch(() => { alert('Something went wrong when trying to retrieve the license!') })
},
components: {
SingleSummarized
// Comments
}
}
</script>
In the created part you can see I also am trying to retrieve a license for the fabmoment using this.fabmoment.license_id. It fails on this line.
Is a tempLicenseID an idea? Because I suspect the this.fabmoment is not available yet. And how would I use this to make the request work? Or any other more sensible solution?
You have to make the request for the licenses after you have retrieved the fabmoment object:
this.$http.get(`/users/${this.$route.params.author_id}/fabmoments/${this.$route.params.fabmoment_id}`)
.then(request => { return this.fabmoment = request.data })
.then( fabmoment => this.$http.get(`/licenses/${fabmoment.license_id`)
.then(request => { this.license = request.data })
.catch(() => { alert('Something went wrong when trying to retrieve the fabmoment attribute data!') })