I'm a beginner and trying to create a practice project. I'm trying to "patch" a data fetched from an API.
My json file looks like this:
{
"classes": [
{
"title": "Office Syndrome",
"length": "60 Minutes",
"instructor": "A. W.",
"difficulty": "Intermediate",
"description": "Suitable for people who are always constantly inactive working in front of computers.",
"availableSpot": "10",
"id": 1
},
{
"title": "Digestive Flow",
"length": "60 Minutes",
"instructor": "MJ",
"difficulty": "Beginners",
"description": "Good for digestion",
"availableSpot": "8",
"id": 2
}
]
I'm trying to create a functionality where the class is bookable where the availableSpot will be decreased by 1 after each booking.
My handleBook function currently looks like this:
const handleBook = (index) => {
setSelectedYogaClass(true);
if (selectedYogaClass === index) {
fetch("http://localhost:8000/classes", {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ availableSpot: data.availableSpot - 1 }),
})
.then((res) => {
if (!res.ok) {
throw Error("Sorry, something went wrong");
}
})
.then((res) => {
console.log(res);
})
.catch((err) => {
setBookingError(err);
});
}
console.log(selectedYogaClass);
setModalIsOpen(false);
};
And this is how I am calling the function
<button
key={index}
onClick={() => handleBook(index)}
className="button button--outline"
>
Yes
</button>
However, I am getting a 404 error and am wondering what the problem is?
Could anyone point out what I am doing wrong?
Thank you so much in advance!
You need to specify specific resource when you use plural routes like http://localhost:8000/classes/:id.
If you want to update(PATCH) the availableSpot field of class with id 1, you should use http://localhost:8000/classes/1
An working example
Related
I'm trying to fetch data from Prepr.io to my program and I want to filter on an object item. The problem what i'm facing is that i dont get all the objects in Javascript/React Native. When i'm doing the exact same request in Postman i got both the objects and when i'm doing the request in Javascript/React Native i only get one object. I want to get both the objects in Javascript but i have no idea of how i can fix this.
Javascript/React Native Fetch request:
const getVideoData = () => {
fetch('https://cdn.prepr.io/publications?fields=items{file{cdn_files},image{cdn_files}}', {
method: 'get',
headers: {
Authorization: 'Bearer abcdefg'
}
})
.then((r) => r.json())
.then((r) => {
console.log(r)
})
.catch((e) => {
console.log(e)
});
};
Javascript/React Native Expo Output:
"beschikbaar_op_route": Object {
"items": Array [
Object {
"body": "Route Groningen Stadspark",
"changed_on": "2022-03-16T14:46:33+00:00",
"created_on": "2022-02-28T12:13:10+00:00",
"id": "a3758c72-1074-4385-884e-34c4bd7d6e1d",
"label": "Tag",
"slug": "route-groningen-stadspark",
},
Postman Request:
Request image
Postman Output:
"beschikbaar_op_route": {
"items": [
{
"id": "a3758c72-1074-4385-884e-34c4bd7d6e1d",
"created_on": "2022-02-28T12:13:10+00:00",
"changed_on": "2022-03-16T14:46:33+00:00",
"label": "Tag",
"body": "Route Groningen Stadspark",
"slug": "route-groningen-stadspark"
},
{
"id": "cc3cbe4b-536a-40e7-b69b-8bdddc24d445",
"created_on": "2022-02-28T12:13:28+00:00",
"changed_on": null,
"label": "Tag",
"body": "Route Leeuwarden Kalverdijkje",
"slug": "route-leeuwarden-kalverdijkje"
}
Been trying all morning and for the life of me I can't get individual array data to be displayed from my API. I am trying to display one body of text from an array at a time, and can only get it to output all at once. Had it working when the data was in JSON format but now its in an array I'm struggling to make it work.
My code:
componentDidMount() {
axios
.get(
"API_DATA"
)
.then((res) => {
let data = res.data
this.setState({ data, loading: false });
console.log(data)
});
}
render() {
if (this.state.loading) {
return <Loader />
}
// return table if loading is false
// handling error goes with the same logic
// table will only render if loading is false
else
return (
this.state.data.data).map((item) => (
<>
<p key={item.id}>{item.title}</p>
</>
))
}
}
I previously used added [0] or [1] etc to determine which element I wanted to display and this worked very nicely however if I try this.state.data.data[0]).map((item) => ( It states it is not a function.
Expected output of API:
{
"data": [
{
"id": 9,
"status": "published",
"body": "TEST1",
"availability": "internal",
"title": "Test1",
"posted_by": "Tester"
},
{
"id": 10,
"status": "published",
"body": "TEST",
"availability": "internal",
"title": "TEST2",
"posted_by": "Tester"
},
I have an array of objects questions.json which looks like
"id": "2",
"ques": "here is my second code ?",
"quesBrief": "I can't seem to find it too.",
"hashes": "#javascript , #goodlord",
"author": "slowdeathv123",
"dateTime": "2021-09-22 18:13:12",
"date": "2021-09-22",
"sortOrder": -99,
"code": " - utlis (folder contains GO files)\n ---sendMail.go \n--templates (folder)\n --- reset_code.html\n - main.go"
I want to add answers array of objects to it to make it a nested object and add more objects to answers array using a fetch/axios/async await request to make it like
"id": "2",
"ques": "here is my second code ?",
"quesBrief": "I can't seem to find it too.",
"hashes": "#javascript , #goodlord",
"author": "slowdeathv123",
"dateTime": "2021-09-22 18:13:12",
"date": "2021-09-22",
"sortOrder": -99,
"code": " - utlis (folder contains GO files)\n ---sendMail.go \n--templates (folder)\n --- reset_code.html\n - main.go"
"answers": [
{
"answerBrief": "Check under the bed",
"answerCode": "no code sorry",
"answerAuthor": "Sonya"
},
{
"answerBrief": "Any other random solution",
"answerCode": "no code sorry",
"answerAuthor": "ABC"
}
],
How to create a post request to add an array of objects inside an object while checking if the answers array already exists, if not create one and add objects to it?
Does this make sense?
let data = {
"id": "2",
"ques": "here is my second code ?",
"quesBrief": "I can't seem to find it too.",
"hashes": "#javascript , #goodlord",
"author": "slowdeathv123",
"dateTime": "2021-09-22 18:13:12",
"date": "2021-09-22",
"sortOrder": -99,
"code": " - utlis (folder contains GO files)\n ---sendMail.go \n--templates (folder)\n --- reset_code.html\n - main.go",
};
const newAnswer = {
"answerBrief": "Check under the bed",
"answerCode": "no code sorry",
"answerAuthor": "Sonya"
};
const answers = [...data.answers || [], newAnswer];
data = {
...data,
answers
}
If you need to add answers that comes after POST request:
fetch('your-api-url-to-add-answers', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data) // data with answers i think?
})
.then(res => res.json())
.then(answersData => {
const answers = [...data.answers || [], answeersData];
data = {
...data,
answers
}
});
If you need to send data with updated answers:
const answers = [...data.answers || [], answeersData];
const payload = {
...data,
answers
}
fetch('your-api-url-to-add-answers', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(payload) // data with answers i think?
})
.then(res => res.json())
.then(answersData => {});
But for a more accurate answer, provide a little more detail. What data needs to be sent in a post request, and what kind of response you receive from the server.
So I am reasonably new to using API's with Js but I am struggling a lot to understand how the Google Fit API works. I am attempting to add a new Workout's data to the API by adding a session and some data for the intensity (heart points) of the session. I can get the session to appear correctly but run into constant errors when I try to create a dataSource and add a point to it for the session. It would be greatly appreciated if someone could help me to fix my code to achieve this or could direct me to a more thorough example of similar code as the API docs don't seem to be too well detailed with examples etc. Thanks in advance.
Here's the 3 api calls that I have written so far, one for creating the DataSource, one for the DataPoint and one for the Session. The session works correctly and adds a session of 1 hr for the correct activity but I am unable to get any of the other API requests to work.
Data Source :
``gapi.client.fitness.users.dataSources.create({
"userId":"me",
"resource": {
"application": {
"name": "LittleWorkouts"
},
"dataType": {"field":[{
"format": "floatPoint",
"name": "com.google.heart_minutes"
}],
"name": "com.google.heart_minutes"
},
"device": {
"manufacturer": "op",
"model": "6",
"type": "phone",
"uid": "1000019",
"version": "1"
},
"type": "raw"
}
})
.then(function(response) {
// Handle the results here (response.result has the parsed body).
console.log("Response", response);
},
function(err) { console.error("Execute error 1", err); });
``
Data Point :
``
gapi.client.fitness.users.dataSources.datasets.patch({
"dataSourceId":"raw:com.google.heart_minutes:292824132082:op:6:1000019",
"userId": "me",
"datasetId": "1592087806561000000-1592287806561000000",
"resource": {
"minStartTimeNs": "1592087806561000000",
"maxEndTimeNs": "1592287806561000000",
"dataSourceId": "raw:com.google.heart_minutes:292824132082:op:6:1000019",
"point": [
{
"startTimeNanos": "1592087806561000000",
"endTimeNanos": "1592287806561000000",
"value": [
{
"fpVal": 89.1
}
],
"dataTypeName": "com.google.heart_minutes"
}
]
}
})
.then(function(response) {
// Handle the results here (response.result has the parsed body).
console.log("Response", response);
},
function(err) { console.error("Execute error 2", err); });
``
Session :
``gapi.client.fitness.users.sessions.update({
"userId":"me",
"sessionId": "someSessionId19",
"id": "someSessionId19",
"name": "Awesome Workout19",
"description": "A very intense workout",
"startTimeMillis": new Date().getTime() - 3600000,
"endTimeMillis": new Date().getTime(),
"version": 1,
"lastModifiedToken": "exampleToken",
"application": {
"detailsUrl": "http://example.com",
"name": "LittleWorkouts",
"version": "1.0"
},
"activityType": 21,
"activeTimeMillis": 3600000
}).then((res) => {console.log(res)});
console.log('res')
//request.execute((res) => {console.log(res);console.log('executrd')})
console.log(auth2.currentUser.get().getBasicProfile().getGivenName());
var request2 = gapi.client.fitness.users.sessions.list({
"userId":"me"
}).then((res) => {console.log(res)})
``
Error message
{message: "Unable to fetch DataSource for Dataset: raw:com.google.heart_minutes:292824132082:op:6:1000019", domain: "global", reason: "invalidArgument"}
It looks like it could be that you're trying to pass in the wrong fields for the data type: if you want to use a standard data type (like com.google.heart_minutes), you should either pass the exact fields of the standard data type (the field should be called "intensity"); or just pass the data type name, and the backend will fill them in for you.
So, if you change the data type to
"dataType": {"name": "com.google.heart_minutes"}
It should work.
Then, you need to use the data source ID returned from that request for the data points.
Awesome, so after some support in the comments I have some working code to add a new session with data from a previously defined data source using 3 API calls. The first call is to create a data source and only needs to be run once. The second and third then add a data point to a data set and creates a new session for the workout respectively. Here's the final working code:
Data Source:
/*
gapi.client.fitness.users.dataSources.create({
"userId":"me",
"resource": {
"application": {
"name": "LittleWorkouts"
},
"dataType": {
"name": "com.google.heart_minutes"
},
"device": {
"manufacturer": "op",
"model": "6",
"type": "phone",
"uid": "1000020",
"version": "1"
},
"type": "raw"
}
})
.then(function(response) {
// Handle the results here (response.result has the parsed body).
console.log("Response", response);
},
function(err) { console.error("Execute error 1", err); });
*/
Data and Data Set:
gapi.client.fitness.users.dataSources.datasets.patch({
"dataSourceId":"raw:com.google.heart_minutes:108881196053:op:6:1000020",
"userId": "me",
"datasetId": z,
"resource": {
"minStartTimeNs": workoutStartTime * 1000000,
"maxEndTimeNs": workoutEndTime * 1000000,
"dataSourceId": "raw:com.google.heart_minutes:108881196053:op:6:1000020",
"point": [
{
"originDataSourceId": "raw:com.google.heart_minutes:108881196053:op:6:1000020",
"value": [
{
"fpVal": 8
}
],
"dataTypeName": "com.google.heart_minutes",
"endTimeNanos": workoutEndTime * 1000000,
"startTimeNanos": workoutStartTime * 1000000,
}
]
}
})
.then(function(response) {
// Handle the results here (response.result has the parsed body).
console.log("Response", response);
},
function(err) { console.error("Execute error 2", err); });
Session:
gapi.client.fitness.users.sessions.update({
"userId":"me",
"sessionId": id,
"id": id,
"name": "Morning Workout",
"description": "A very intense workout",
"startTimeMillis": workoutStartTime,
"endTimeMillis": workoutEndTime,
"version": 1,
"lastModifiedToken": "exampleToken",
"application": {
"detailsUrl": "http://example.com",
"name": "LittleWorkouts",
"version": "1.0"
},
"activityType": 21,
"activeTimeMillis": workoutEndTime - workoutStartTime
}).then((res) => {console.log(res)});
console.log('res')
I am finishing a my personal social network/e-commerce hybrid project, i try to map through the reviews array and than filter the likes array which is empty and should carry on reading the code, but somehow it gives me 'User has already liked this' error, which is supposed to fire if user has liked the review posted to this product, but the likes arrays are empty.
I have lost count to what have i tried fixing this, since i am fairly a new dev, I wasn't able to find a solution to this, I won't be surprised if it's really a very basic mistake :D
This is one of the products. I have created some reviews, and try to like them
{
"_id": "5c937d124b068106100f4f7e",
"name": "Assasin's Creed 3 Remastered",
"developer": "Ubisoft",
"image": "https://ubistatic19-a.akamaihd.net/ubicomstatic/en-us/global/game-info/ac3r_naked_boxshot_tablet_343557.jpg",
"image2": "http://ngerandom.com/wp-content/uploads/2019/02/Assassins-creed-3-test-bild-7.jpg",
"genre": "Action-adventure, Stealth",
"trailer": "https://www.youtube.com/watch?v=9IupDCUCFK4",
"release": "29.03.2019",
"platforms": "PC, PS4, Xbox One",
"__v": 6,
"reviews": [
{
"_id": "5c9b5bf4e9e15b17008a69e8",
"text": "good comment",
"user": "5c8acf4b62b2590f8c9221ce",
"likes": [],
"dislikes": [],
"comments": [],
"date": "2019-03-27T11:18:12.846Z"
},
{
"likes": [],
"dislikes": [],
"comments": [],
"date": "2019-03-27T08:23:27.959Z",
"_id": "5c9b32ff09a9342188ddc35a",
"text": "A very good game once more",
"user": "5c8acf4b62b2590f8c9221ce"
}
]
}
This is the code that has to like it
router.post(
"/like/:product_id/:id",
passport.authenticate("jwt", { session: false }),
(req, res) => {
Profile.findOne({ user: req.user.id }).then(profile => {
Product.findById(req.params.product_id)
.then(product => {
if (
product.reviews.map(
review =>
review.likes.filter(
like => like.user.toString() === req.user.id
).length > 0
)
// product.likes.filter(like => like.user.toString() === req.user.id)
// .length > 0
) {
console.log(product.reviews.toString());
return res
.status(400)
.json({ alreadyliked: "User already liked this product" });
This is the error that i get
{
"alreadyliked": "User already liked this product"
}
I have been trying to fix this last 4 hours, I won't be able to thank you enough if you'll try to help me fix this
Your problem is the if that is always true.
Your .map + filter are creating an array of boolean.
if([false, false, false]) is always true (also if([]) will be true).
So you need to simplify the condition logic: maybe using [].some or [].every based on your needs.
const bools = product.reviews.map(
review => review.likes.filter( like => like.user.toString() === req.user.id ).length > 0
)
if (bools.some(b => b === false)){ ...