My PATCH request is showing as successful, but nothing is being updated - javascript

Trying to make a simple patch request against a single document, and the request returns
{
"acknowledged": true,
"modifiedCount": 1,
"upsertedId": null,
"upsertedCount": 0,
"matchedCount": 1
}
This is the document I am trying to update
{
"_id": "63843e60079d9cdf9c26505a",
"name": "AKG_HSD271",
"image": "images/Products/AKG_hsd271.png",
"colour": "Black",
"description": "AKG HSD271 over-ear headset",
"price": "165.99",
"startingDateAvailable": "2022-05-10T15:23:28.000Z",
"type": "Over-Ear",
"isOnSale": false,
"stock": 46,
"EndingDateAvailable": "N/A",
"manufacturer": "AKG",
"updatedAt": "2022-12-03T08:48:35.302Z"
}
This is the request body I am sending (via Postman)
{
"price": "100.99"
}
And here is the code for my route handler
router.patch('/Products/:id', (req, res) => {
console.log('/Products/'+req.params.id);
const updates = req.body;
Product.updateOne({_id: ObjectId(req.params.id)}, {$set: updates})
.then(result => {
console.log(result);
res.json(result);
})
.catch(err => {
res.status(500).send(err.message);
});
});
Can't for the love of me figure out what is going wrong and why the price field won't change, and can't find any threads that have a suggestion I haven't tried. Any ideas?

Found the problem. Including the built in json() function in express before my route handlers seemed to do the trick:
router.use(express.json())
Apparently in express, the body property does not exist on the req object unless you include the json middleware. Hope this helps others.

Related

NextJs & Strapi using getStaticPaths error

Currently I am using Strapi to build out a custom API and NextJs for the front end, I am trying to use getStaticPaths to create pages based on categories. I have setup a categories collection with a relationship to my papers collection in Strapi and when using Postman to test API routes everything works great. However Next is giving me an error when I attempt to access the getStaticPaths route which should http://localhost:3000/categories/1 but instead I get the error Error: A required parameter (category) was not provided as a string in getStaticPaths for /categories/[category] currently my code looks like this below; However I am confused because I am converting it to a string which should fix the error correct? I am no pro at NextJs btw.
If I manually enter the route in either Postman or my browser it works correctly, responding with the correct json output. And the console for strapi also shows the sent request, However this does not appear in the console when Next tries to load the page I am guessing because it isn't getting that far.
How the F do I fix the above mentioned error I have been here for days and it is getting slightly annoying lol
// pages/categories/[category].js
function Category({ categories }) {
return (
<>
<h1>{categories.name}</h1>
<h2>{categories.papers.name}</h2>
</>
)
}
export async function getStaticPaths() {
const res = await fetch('http://localhost:1337/Categories')
const Categories = await res.json()
await console.log(Categories);
const paths = Categories.map((category) => ({
params: { id: category.id.toString() },
}))
return { paths, fallback: false }
}
export async function getStaticProps({ params }) {
// params contains the post `id`.
// If the route is like /posts/1, then params.id is 1
const res = await fetch(`http://localhost:1337/Categories/${params.id}`)
const categories = await res.json()
console.log(categories)
// Pass post data to the page via props
return { props: { categories } }
}
export default Category
The correct response for http://localhost:1337/Categories/**${params.id}** - which should be 1 meaning the url is http://localhost:1337/Categories/1
{
"id": 2,
"name": "English",
"published_at": "2021-10-08T10:12:08.041Z",
"created_at": "2021-10-08T10:12:04.011Z",
"updated_at": "2021-10-08T10:12:08.061Z",
"papers": [
{
"id": 1,
"name": "2020 English Studies (Testing)",
"description": "# Testing",
"PDF_link": "/uploads/2020_hsc_english_studies_98eabce6e7.pdf",
"published_at": "2021-10-08T10:14:55.816Z",
"created_at": "2021-10-08T10:12:48.714Z",
"updated_at": "2021-10-08T10:14:55.835Z",
"Media_Upload": [
{
"id": 1,
"name": "2020-hsc-english-studies.pdf",
"alternativeText": "",
"caption": "",
"width": null,
"height": null,
"formats": null,
"hash": "2020_hsc_english_studies_98eabce6e7",
"ext": ".pdf",
"mime": "application/pdf",
"size": 4959.79,
"url": "/uploads/2020_hsc_english_studies_98eabce6e7.pdf",
"previewUrl": null,
"provider": "local",
"provider_metadata": null,
"created_at": "2021-10-08T10:14:32.827Z",
"updated_at": "2021-10-08T10:14:32.847Z"
}
]
}
]
}
Keys in params should correspond to your dynamic route name. You pass id key there, but your route is called /categories/[category] so you need to pass category key.
const paths = Categories.map((category) => ({
params: { category: category.id.toString() },
}))
And in getStaticProps obviously also grab category from params.

Mongoose findOneAndUpdate is not updating the document, instead it is creating a new one?

I am using Node, Express, and MongoDB/Mongoose for my backend. I have this PUT route set up:
//where id is the unique id of the review, not the movie
router.put('/update/:id', [jsonParser, jwtAuth], (req, res) => {
Review.findOneAndUpdate(req.params.id,
{ $set: { ...req.body } }, { new: true })
.then(review => {
console.log(review);
res.status(203).json(review);
})
.catch(err => res.status(500).json({message: err}));
});
Using Postman upon creating a new document on my POST route, the response is the following:
{
"genre_ids": [
"28"
],
"_id": "5ce112d0aeadc44ea0ea7bb0",
"movieId": 447404,
"title": "Pokemon Detective Pikachu",
"poster_path": "/wgQ7APnFpf1TuviKHXeEe3KnsTV.jpg",
"reviewer": "5cda5d08f3a74252c83b4a63",
"reviewTitle": "the best",
"reviewText": "new review",
"reviewScore": 5,
"__v": 0
}
Using Postman when I try to update the following document on this url
.../review/update/5ce112d0aeadc44ea0ea7bb0 where the id the is taken from _id of the POST response above.
I make a very simple change in the PUT request just to change the score.
{
"reviewScore": 1
}
I then get the following response from the PUT route.
{
"genre_ids": [
"28"
],
"_id": "5ce089116b537a08403ed25f",
"movieId": 447404,
"title": "Pokemon Detective Pikachu",
"poster_path": "/wgQ7APnFpf1TuviKHXeEe3KnsTV.jpg",
"reviewer": "5ce0882d90b63613700b066a",
"reviewTitle": "the best",
"reviewText": "updated review",
"reviewScore": 1,
"__v": 0
}
You can see that in the PUT request response, both the _id and reviewer have changed. In fact, it has created a new document for another user, instead of updating the original document. If I login to the account belonging to _id that's given from the PUT response, it does indeed show that a new document was created for that account and not updated the document for the other/original account.
Why is this happening? Please help.
You need to provide the conditions as an object.
router.put('/update/:id',
[jsonParser, jwtAuth],
(req, res) =>{
Review.findOneAndUpdate({'_id' :req.params.id}, { $set: { ...req.body } }, { new: true })
.then(review => { console.log(review);
res.status(203).json(review);
})
.catch(err => res.status(500).json({message: err}));
}
);
Or if you want to directly use the id like in your code, just replace findOneAndUpdate to findByIdAndUpdate.
Check out Mongoose Query API

How to store Exception/Error from Azure function js?

I have created an Azure function to save data in SQL database from Iot Hub that is working fine, Now I want to save Exception and Error to Azure storage Table so for that I have added try{ } catch(err){} but that is not working. please correct me. Thanks!
my function is here
module.exports = function (context, iotHubMessage) {
try {
var strMsg = JSON.stringify(iotHubMessage);
context.log('Message received: ' + strMsg);
var ob1 = { "employee_idw": 444, "last_name": "Teller", "first_name": "Saara", "age": 34, "salary": 87000 };
//I misspelled 'employee_idw' to generate error
var ob2 = { "employee_id": 555, "last_name": "Teller", "first_name": "Saara", "age": 31, "salary": 87000 };
ob1.EventProcessedUtcTime = new Date;
ob2.EventProcessedUtcTime = new Date;
var arr = [];
arr.push(ob1);
arr.push(ob2);
context.bindings.outputTable = arr;
context.done();
} catch (err) {
context.log('CCC Error' + err); // even can not see this message in log
context.bindings.error= { "partitionKey": partitionKey, "rowKey": rowKey, "data": err };
}
};
see this is JSON file
{
"bindings": [
{
"type": "eventHubTrigger",
"name": "myEventHubMessage",
"path": "myeventhub",
"consumerGroup": "$Default",
"connection": "PBCorIOTHub_events_IOTHUB",
"cardinality": "many",
"direction": "in"
},
{
"type": "apiHubTable",
"name": "outputTable",
"dataSetName": "default",
"tableName": "employees",
"connection": "sql_SQL",
"direction": "out"
},
{
"type": "table",
"name": "error",
"tableName": "dddtTest",
"connection": "cccteststr_STORAGE",
"direction": "out"
}
],
"disabled": false
}
Are you using Azure SQL or Azure table storage to store the data? From your code it looks like you are using Azure table storage. The reason i ask is because a changed property name would not cause an error in function. Instead the table storage would create a new property with misspelled name.
Like Mikhail suggested the to store an error caused inside of a function all you have to do is create another output binding and assign the exception to it.
However not all exceptions occur inside of a function context. For example an error in function.json configuration could cause a error connecting to storage. This would cause function execution to fail outside of function code context. Azure functions has direct integration with Application Insights and can help monitor what you are looking for. Here is a blog post that can shows how to configure Application Insights.
https://blogs.msdn.microsoft.com/appserviceteam/2017/04/06/azure-functions-application-insights/

How can I post a container in Storage api from loopback?

I already have declared my datasource ,my model and the connector between these.
My model
{
"name": "container",
"base": "Model",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {},
"validations": [],
"relations": {},
"acls": [],
"methods": {}
}
Datasource
"storage": {
"name": "storage",
"connector": "loopback-component-storage",
"provider": "filesystem",
"root": "./server/storage"
}
My provider
{
"filesystem": {
"root": "./server/storage"
}
}
And the Connector
"container": {
"dataSource": "storage",
"public": true
}
I try posting a object like {"Object":"container1"} into path "./server/storage" but I get the following error from callback.
{
"error": {
"statusCode": 500,
"name": "TypeError",
"message": "Path must be a string. Received undefined",
"stack": "TypeError: Path must be a string. Received undefined.."
}
}
Please who can help me to find my issue? Thanks!
You can also use "name" instead of "Object" as key in your JSON object to create a new container/directory using the API.
POST /api/containers {"name":"container1"}
The way to post a container is, without using the loopback api. Create a folder that is gonna be the container into your provider path (being filesystem).
As simple as that!
If you need a programmatic way to add new containers, let's say for example you want to create a filesystem of sorts for new users. You can use the route below. "Container" is the name I called my Model, you can call yours whatever you'd like.
POST localhost:3000/api/container
Inside the body of the post request you have to have an attribute name and the value of the name can be the new container you're creating. The Strongloop/Loopback documentation, which can be found here, is not accurate and neither is the error you get back when you try to post it with their directions.
"error": {
"statusCode": 500,
"name": "TypeError",
"message": "Path must be a string. Received undefined"
}
An excerpt of the code to send a post request to create a new container is also below.
var request = require("request");
var options = {
method: 'POST',
url: 'http://localhost:3000/api/containers',
body: { name: 'someNewContainer' },
json: true
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});

Unexpected token < in JSON at position 0

If I do curl, the server returns an array of posts objects, like this:
curl http://localhost/api/posts/
[
{
"id": 7,
"target": {
"body": "This is the body",
"title": "Airbnb raising a reported $850M at a $30B valuation",
"user": {
"first_name": "ben",
"last_name": "jamin"
}
}
},
{
"id": 11,
"target": {
"body": "This is the body",
"title": "Browsing the APISSS",
"user": {
"first_name": "user",
"last_name": "two"
}
}
}
]
I tried getting this using the fetch api:
fromServer() {
console.log('fromServer')
var headers = new Headers();
headers.append('Accept', 'application/json');
let a = fetch('http://test.com/api/posts/', headers)
.then(function(response) {
if (response.status !== 200) {
console.log('There was a problem. Status Code: ' + response.status);
return;
}
response.json().then(function(data) {
console.log(data);
});
}
)
.catch(function(err) {
console.log('Fetch Error :-S', err);
});
}
But I am getting this error:
Unexpected token < in JSON at position 0
SyntaxError: Unexpected token < in JSON at position 0
How can I solve this problem? Could you please help me. Thank you.
It is clear that you have some syntax error while parsing response into json object.
Remove all the comments from server json file if any.
If it is not:
I believe the response body is not json.
You're receiving HTML (or XML) back from the server, but code is enable to parse as JSON.
Check the "Network" tab in Chrome dev tools to see contents of the server's response.
Or debug using this code: (as "Jaromanda X" said)
.then(function(response) {
console.log(response);
console.log(response.status);
console.log(response.json());
console.log(response.text());
})
.catch(function(err) {
console.log('Fetch Error :-S', err);
});
You can try adding the dataType property,just like dataType: 'html' or dataType: 'text'
Please check that your server is giving response in JSON format only. It should not be a string.
For Associative data you should start your JSON object with { not [ .
So your data should be in below format:
{
"data": [
{
"id": 7,
"target": {
"body": "This is the body",
"title": "Airbnb raising a reported $850M at a $30B valuation",
"user": {
"first_name": "ben",
"last_name": "jamin"
}
}
},
{
"id": 11,
"target": {
"body": "This is the body",
"title": "Browsing the APISSS",
"user": {
"first_name": "user",
"last_name": "two"
}
}
}
]
}
And you can get all data from response.data .
For more detail follow this link .
The wording of the error message corresponds to what you get from Google Chrome when you run JSON.parse('<...'). I know you said the server is setting Content-Type:application/json, but I am led to believe the response body is actually HTML.
"SyntaxError: Unexpected token < in JSON at position 0"
with the line console.error(this.props.url, status, err.toString()) underlined.
The err was actually thrown within jQuery, and passed to you as a variable err. The reason that line is underlined is simply because that is where you are logging it.
I would suggest that you add to your logging. Looking at the actual xhr (XMLHttpRequest) properties to learn more about the response. Try adding console.warn(xhr.responseText) and you will most likely see the HTML that is being received.
Please correct your code according to above explanation.
so, you can use with start JSON array ;
{
"array": [
{
"id": 7,
"target": {
"body": "This is the body",
"title": "Airbnb raising a reported $850M at a $30B valuation",
"user": {
"first_name": "ben",
"last_name": "jamin"
}
}
},
{
"id": 11,
"target": {
"body": "This is the body",
"title": "Browsing the APISSS",
"user": {
"first_name": "user",
"last_name": "two"
}
}
}
]
}
So the problem was this: Since I was testing it from the vagrant machine in LAN and in my hosts file I added the ip of vagrant machine as the url (test.com), the device was not able to fetch to that url. After I changed the vagrant machine to port forward and gave the original IP address of the machine, I was able to fetch the json objects. Thank you all for your help.
In my case, the port I was trying to use was already in use. I solved this issue by executing the follwing command in the command prompt in order to terminate the port.
taskkill /F /IM node.exe

Categories