I recently encounter a problem that is regarding to the CRUD development process. When I update a property and send the response to the postman, postman always display the previous data. For example, after I clicked send on Postman, it displays "weeks" : "11" instead of "10". ==>First Click
Then when I click the send button the second times, it updates the postman display "week" : "10" instead. ===> Second Click
Have anyone encounter this problem before? What is the best solution?
Here is the link to the code related to my questions: https://codesandbox.io/s/pensive-tdd-c9rej
I just don't know if this only happens to postman or it does happen to all the final production as well.
I will answer you real quick. You just need to add some options to the query.
You should set the new option to true to return the document after update was applied.
https://mongoosejs.com/docs/tutorials/findoneandupdate.html#:~:text=As%20the%20name%20implies%2C%20findOneAndUpdate,was%20before%20update%20was%20applied.&text=You%20should%20set%20the%20new,document%20after%20update%20was%20applied.
exports.unblockUser = withCatchErrAsync(async (req, res, next) => {
const { userId } = req.params;
// **blocked** is set to hidden by default, now we explicitly turn that back on
const doc = await User.findByIdAndUpdate(
userId,
{ blocked: false },
// The key Code is here
{
new: true,
runValidators: true,
}
).select("+blocked");
if (!doc) {
return next(new OperationalErr("User ID does not match any user"), 400);
}
return res.status(200).json({
status: "success",
data: {
user: doc,
},
});
});
Related
I am exploring next.js with mongodb, however I faced a problem that I can't find an appropriate soulution on the Internet.
I have an api handle different request.
For the GET method, I want to pass different parameters(i.e. category and subcategory in this case) to apply different filters to grap data from mongodb.
Since there can be multiple subcategories, now the question is how can I properly perform the in-clause query here? I would like to perform something like
select * from post where category="music share" AND subcategoy in ("rock","metal")
It works fine when there is one subcategory only, but it will not work when there are more.
For the non working test case, current console.log returns-> query is: { category: 'music share', subcategory: 'rock,metal' }
async function getPosts(req,res){
var query={};
if (req.query.category){
query.category=req.query.category;
}
if (req.query.subcategory){
query.subcategory=req.query.subcategory;
}
try {
console.log("query is: ",query);
// connect to the database
let { db } = await connectToDatabase();
// fetch the posts
let posts = await db
.collection('posts')
.find(query)
.sort({ _id: -1 })
.toArray();
// return the posts
return res.json(JSON.parse(JSON.stringify(posts)));
} catch (error) {
// return the error
return res.json({
message: new Error(error).message,
success: false,
});
}
}
I have this view in the playground:
But when I try to add another option to select, I hit CTRL + space and I see every single possible option, even the ones already selected.
How can I stop that from happening? In the dropdown I'd like to see only the options I still can select, not the ones already selected.
Here's my index.ts
const app = express();
(async () => {
const schema = await buildSchema({ resolvers: [ UserResolvers ] });
const server = new ApolloServer({ schema });
server.applyMiddleware({ app });
createConnection({
type: 'mysql',
...dbData,
entities: [
Availability,
Chat,
Meeting,
Message,
Offer,
Tag,
User,
],
synchronize: true,
logging: true,
})
.then(() => {
app.listen({ port: 4000 }, () => {
console.log(
`🚀 Server ready at http://localhost:4000${ server.graphqlPath }`,
);
});
})
.catch((error) => console.log(error));
})();
There is no option to change this behavior. You can open an issue in the GraphiQL repo (GraphQL Playground is effectively deprecated and will be merged into GraphiQL) to request this feature.
However, it's also unlikely that such a feature will ever be supported. Duplicate field names are perfectly valid in GraphQL. In addition, it's not uncommon to request the same field multiple times using a different alias and a different set of arguments for each instance of the field:
query {
activeUsers: users(isActive: true) {
...UserFragment
}
inactiveUsers: users(isActive: false) {
...UserFragment
}
}
In that context, omitting a field from the list of suggestions just because it was already included in the selection set doesn't really make sense.
I have a local Java Service that exposes a single endpoint where the response can take over 5min sometimes depending on the request size. I want to "hide" this endpoint behind Strapi, so that a user that is not authenticated through Strapi, can't access this endpoint. What i've done is, created a custom Route in Strapi, and created a custom controller function for this route:
async optimizeRoute(ctx) {
try {
console.log(`${new Date()} - Optimize route started`)
const vehicles = ctx.request.body.vehicles.map(vehicle => {
return {
id: vehicle.id,
licenseplate: vehicle.licenseplate,
maxweight: vehicle.maxweight,
maxlength: vehicle.maxlength,
geojson: vehicle.geojson,
maxtime: moment(vehicle.endtime).diff(moment(vehicle.starttime), 'seconds') * 1.1
}
});
const orders = ctx.request.body.orders.map(order => {
return {
id: order.id,
weight: order.weight,
length: order.length,
geojson: order.geojson
}
});
console.log(`Using ${vehicles.length} vehicles, and ${orders.length} orders!`)
const response = await axios.post('http://127.0.0.1:9090/optimizeroutes',
{ vehicles: vehicles, orders: orders }, {timeout: 0}
);
return response.data;
} catch (error) {
ctx.throw(error.response.status, error.response);
}
}
But what happens when i do this, is Strapi closes the connection after 1-2 min to the requester before the response is returned.
Using Strapi Beta3.17.5.
Anywhere i can configure or debug to wait for the axios to return a response then return the response to the requester??
The default server timeout value is 2 min, Please check the image for reference.
So in server.js you can increase this timeout value by passing callback function
So the code will look like below
const strapi = require('strapi');
strapi(/* {...} */).start(()=>{
strapi.server.setTimeout(0);
});
setting timeout to 0 strapi will wait forever or you can add value in milliseconds.
Thank you for putting me on the right track #NS23, but i couldn't user server.js to start my server, and console logging strapi.server returned undefined.
What i did though was access strapi.server in Bootstrap.js, which then logging strapi.server, could see the timeout was changed from 120000 to 0
I think this is related to how I've defined my schemas, but I can't seem to find where the bug is... I have an almost identical file set up that's working perfectly and I've unfortunately not been able to find a duplicate of this issue anywhere.
When sending an API request to my local Express instance via Postman, only the 'title' request body value is stored in the database. I am sending the following simple request to my route as Application/Json (thought the same happens when using x-www-form-urlencoded):
{
"postTitle": "title goes here",
"postContent": "body goes here",
"isPublished": true
}
This is clearly being registered in express, as if I log the object I can see this data (plus timestamps and an _id):
{ _id: 5b07d9c0b8124e0599079c04,
postTitle: 'title goes here',
postContent: 'body goes here',
isPublished: true,
createdAt: 2018-05-25T09:39:12.869Z,
updatedAt: 2018-05-25T09:39:12.869Z,
__v: 0 }
However, when I send a get request to my route on this object using its ID, I receive the following in response:
{ "_id": "5b07d9c0b8124e0599079c04" }
Likewise, if I send a request to list all objects, I receive the following response:
{
"posts": [
{
"_id": "5b07d9c0b8124e0599079c04"
},
{
"_id": "5b07d9c0b8124e0599079c03"
},
{
"_id": "5b07d9914f10ce058f137eba"
}
]
}
Weirdly, sometimes the post title sent as part of the response is included in the response, and sometimes it isn't.
My schema is as follows:
var postSchema = new Schema({
postTitle: String,
postContent: String,
isPublished: Boolean
},
{
timestamps: true
});
My post API route for POST requests is as follows:
router.post('/posts', (req, res, next) => {
var postTitle = req.body.postTitle;
var postContent = req.body.postContent;
var isPublished = req.body.isPublished;
var newPost = new Post({
postTitle: postTitle,
postContent: postContent,
isPublished: isPublished
});
newPost.save(function (error) {
if (error) {
console.log(error)
}
res.send({
success: true,
message: 'Post saved successfully!'
})
})
});
(If you're not using Router, you'll have 'app.post' instead of 'router.post') Again, this is a bit longwinded but everything works fine.
My GET route is as follows:
router.get('/posts', (req, res) => {
Post.find({}, 'title content published', function (error, posts) {
if (error) { console.error(error); }
res.send({
posts: posts
})
}).sort({_id:-1})
});
OK - so, by going through my code in detail I've figured out where I was going wrong and fixed the issue, however, in my searching I found very little in the way of results. I'm pretty new to Express, so I'm going to outline the cause of the issue and how I resolved it in order to potentially save someone else a bunch of time if they make the same stupid mistake.
Now, the issue I'm having results from the way I was retrieving the data and serving that in response to get requests. As an example, here's my GET route to list all of the objects.
I was entirely focusing on the post request and assuming it was a problem with the database. It turns out what I'd actually done, is in order to make my schemas and routes less confusing, I'd changed the names of the relevant variables. What I'd forgotten to do, however, is update this line in my GET route to reflect the change:
Post.find({}, 'postTitle postContent isPublished', function (error, posts) {
Which I'd left as:
Post.find({}, 'title content published', function (error, posts) {
The reason the title sometimes displayed is that I tried undoing changes back and forth to spot the issue.
I know this is a super basic query but I got stuck on this for the best part of a day, and the only other relevant discussion on this ended with OP saying that it magically fixed itself.
I have the following code in my Model.js file.
Model.observe('loaded', (ctx, next) => {
const {
data,
options: {
user
}
} = ctx;
const owner = (user && data && user.uid === data.userId) || false;
console.log(
`${data.id}: loaded - access by ${user && user.name}, owner:${owner}`
);
if (!owner) {
delete data.testProp1;
}
console.log('returning: ', ctx.data);
next();
});
When I make a request, I see the following log output (server logs):
f3f9ffd6-14dc-42e5-94ba-503aa3426faa: loaded - access by User1, owner:false
returning:
{
testProp2: true,
id: 'f3f9ffd6-14dc-42e5-94ba-503aa3426faa',
userId: 'sfeywkKSuBTlf0DwE4ZOFd8RX5E3'
}
But then in the actual response the browser receives I actually get:
{
testProp1: true,
testProp2: true,
id: 'f3f9ffd6-14dc-42e5-94ba-503aa3426faa',
userId: 'sfeywkKSuBTlf0DwE4ZOFd8RX5E3'
}
Is there something in the documentation I am missing? Deleting the property is exactly what it shows in the Loopback docs here. Also, I actually see the modified data as the data property on the ctx object before calling next(). Anyone run into this issue or know some caveat to the docs that isn't explicitly stated?