I have a backend strapi-service and i try to post a JSON to it with axios. It creates the new Content with an ID, but the JSON is empty. As a response it returns null.
I am using react-js. My Code:
import axios from 'axios';
function App() {
const apiUrl = 'http://localhost:1338/api/participants'
const posting = async () => {
await axios.post(apiUrl,{
"data": {
"startStudyTime": 0,
"endStudyTime": 0,
"objectsPressed": [{}],
"searchHistory": [{}],
"connection": {
"Device": "",
"Browser": "",
"OS": ""
},
"finished": false,
"canceled": false
}
}, { headers: { 'Content-Type': 'application/json' } })
.then( response =>{
console.log('response.data:', response.data)
console.log('response.data.data:', response.data.data)
console.log('response.data.data.id:', response.data.data.id)
})
}
return (
<div className="App">
<button onClick={posting}>Submit</button>
</div>
);
}
export default App
The code runs and when I press on the submit-button, I'll always get a log, where the data has a diffrent id, but the participantLoggingData remains null, as the postman log below.
So i tried to use postman to see if anything is wrong with axios or sth:
I used the "post" call, put the Json object into the body, set the body to raw and JSON and got the following:
{
"data": {
"id": 27,
"attributes": {
"participantLoggingData": null,
"createdAt": "2022-11-07T00:23:41.759Z",
"updatedAt": "2022-11-07T00:23:41.759Z",
"publishedAt": "2022-11-07T00:23:41.759Z"
}
},
"meta": {}
}
and the json is stil null, idk...
I tried stuff like JSON.stringify() this gave me a 400 error and i tried to store the json into a container, so i can all sth like await axios.post(apiUrl, data,{ headers: { 'Content-Type': 'application/json' } }), but nothing worked.
So I looked up the strapi documentation and i couldn't find any diffrence(syntax-wise), so i guess my strapi isn't set up 100% correct. If I create a new contentType with only a Json it has the same issue. Is there a fix for it?
My strapi configs:
Under Settings/Roles/Public/Participant, all boxes are checked, so basicly everyone should be able to create, find, update and delete stuff.
My ContentType is called Participant with a JSON named "participantLoggingData"
I also have tried to use the axios.put call, but this doesnt change the object, it still remains empty :/
For json field participantLoggingData in your post request you need to send data like:
{
"data": {
"participantLoggingData": {
"startStudyTime": 0,
"endStudyTime": 0,
"objectsPressed": [{}],
"searchHistory": [{}],
"connection": {
"Device": "",
"Browser": "",
"OS": ""
},
"finished": false,
"canceled": false
}
}
}
You cannot directly pass data in data key in this case.
Related
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.
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.
I am calling an HTTP POST Request, the response is JSON data.
POST Request:
const postXHR = new XMLHttpRequest();
postXHR.open('POST', postOptions);
postXHR.setRequestHeader("Accept", "text/json");
postXHR.setRequestHeader("Content-Type", "text/json");
postXHR.onreadystatechange = function() {
const response = postXHR.response;
if (response.response) {
console.log(postXHR.status);
}
createNewOptionValues(response);
}
postXHR.send('{"optionName":"optionName46", "platformName":"platformName46","dotDigitalId":3,"googleId":4}');
POST Response/JSON Data:
{
"data": {
"rooftopGoogleOptionId": 99,
"googleId": 4,
"dotDigitalId": 3,
"optionName": "optionName46",
"optionValue": null,
"platformName": "platformName46",
"googleAccount": null,
"dotDigitalAccount": null,
"updatedBy": null,
"updatedAt": null,
"createdBy": "root",
},
"status": 201,
"message": "success"
}
The createNewOptionValue function should log the value of a property within the response.
function createNewOptionValues(obj){
console.log(obj.googleId);
console.log(obj['googleId']);
}
Yet, the output is undefined, when using console.log(obj), the response does show.
When you receive a response, it is in "text" format (in most of the cases)
So you need to pass that response to JSON.parse for accessing it as a JSON Object.
Adding just 1 line in your createNewOptionValues function will make it work. Also, you need to access obj.data.googleId instead of accessing obj.googleId
function createNewOptionValues(obj){
obj = JSON.parse(obj)
console.log(obj.data.googleId);
console.log(obj.data['googleId']);
}
I'm trying to get the roles of the current user in a specific chat room using Discord's API (using an access_token). I've had a fair look through the docs and can't see how to do this. For example, doing a get request to https://discordapp.com/api/users/#me gives the basic user info as expected. I then tried something along the lines of the following without any luck:
https://discordapp.com/api/users/#me/guilds/${guild.id}/roles
Here's a snippet of the code I'm using:
....get access token then
.then(info => {
console.log(info)
fetch(`https://discordapp.com/api/users/#me`, {
headers: {
authorization: `${info.token_type} ${info.access_token}`,
},
}).then(response => response.json())
.then(info => {
console.log(info)
})
})
Any ideas?
To clarify, the user logs in with discord and my application receives a user access token which I'm then trying to use to get the roles of the user in a specific discord room.
From the documentation you can do this using the endpoint:
GET /guilds/{guild.id}/members/{user.id}
This will return a guild member object that contains the roles of this user.
Example guild member object:
{
"user": {},
"nick": "",
"roles": [],
"joined_at": "",
"deaf": false,
"mute": false
}
There is
GET /users/#me/guilds/{guild.id}/member
Which will get you a JSON object containing
{
"avatar": null,
"communication_disabled_until": null,
"flags": 0,
"is_pending": null,
"joined_at": "2023-01-11T23:12:34.423000+00:00",
"nick": null,
"pending": null,
"premium_since": null,
"roles": [
2888141278217623600,
5904405471246944000
],
"user": {
"id": 8285334657500223000,
"username": "your-name",
"display_name": null,
"avatar": null,
"avatar_decoration": null,
"discriminator": 4041,
"public_flags": 0
},
"mute": null,
"deaf": null
}
To use this with OAuth2, you must request the guilds.members.read OAuth2 scope, which is the one that Discord prompts users for their permissions with
Read your member info (nickname, avatar, roles, etc...) for servers you belong to
This was added in sometime in late 2021, judging from this PR.
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);
});