Exploiting the id from the HTTP response after dispatching crudCreate action - react-admin

I am creating form in which I must post one input before the others.
I must get the id from that post before I post the rest of the Form.
I have successfully dispatched the create action.
const createPromise = Promise.resolve(
this.props.crudCreate(
this.props.reference,
{ description: this.state.addInputValue },
this.getBasePath(),
null,
)
);
createPromise.then(res => console.log(res))
After dispatch, I can log via the promise the following:
However, I am, looking to get the response body after the post which would be my id as seen below.
I thought about adding the functions from ReferenceInputController in my component but it does not seem be a good practice.
What would be the best way to get the id from the HTTP response?

Related

api request problem response 500 from backend

All welcome, I ran into a problem in which at the time of passing id and body in the method it is received, it gives 500 errors. In swagger I have an infected method, it looks like this:
swagger
Accordingly, in the body of the request, I pass all the parameters of the fields it needs (I drive them in strictly, just to check for operability):
code
In response I get this:
response
If you try to do the same in the swagger, then the method works and a 200 response comes:
swagger 200 response
What am I doing wrong?
I tried to make the code asynchronous, I tried to pass fields in different ways, but nothing happens, the answer comes 500
Try to put the id field inside the obj.
const form = {
id: 790,
...
}
You are passing too much params inside the callback (id, form).

Second parameter in express route handler

I'm coming across code where there's an additional parameter for express route handlers beyond the path and the callback.
For example:
app.get('/path', authUser, (req,res) => {
...
}
where authUser is a function. Can anybody explain the role of such functions? To date I've only seen express routes with the two parameters.
These are middleware, which are functions that run before your route handler (your third function). You can have as many as these as possible. They basically modify/perform an action based on the request, or maybe manipulate the response.
So this is likely middleware that checks the request for an authenticated user, and will return a 401/403 if not authenticated, meaning that you can write your route handler under the assumption that you are authenticated.
For more info, check out this article
The family of methods such as app.get(), app.post(), app.use(), accept any number of request handlers as successive arguments:
app.get('/path', fn1, fn2, fn3, fn4);
These requests handlers can be used for a variety of purposes. Often times, they are what is generally referred to as middleware which prepares a request for further processing or in some cases blocks a request from further processing. But, they can also be normal request handlers too, they are not just limited to what most people call middleware.
In your specific case:
app.get('/path', authUser, (req,res) => {
...
}
We can guess by the name that authUser is checking to see if the user making the request has been properly authenticated and, if not, then an error status is probably sent as the response and the next request handler in the chain is not called. Or conversely, because authUser has already filtered out any unauthenticated users, the request handler here at the end of the chain can safely assume that the user is already authenticated. So, this particular use is a means of applying middleware to one specific route with no consequences for any other routes defined later.
But, I want to emphasize that this is a generic mechanism that is not limited to just what is classically described as middleware. It can also be used for request handlers that might execute conditionally based on other parameters. For example here's one such example where the first request handler looks the URL and decides to handle the whole request itself based on what it sees in the URL and, if not, passes it on to the next handler:
app.get('/book/:id', (req, res) => {
// check if id is purely numeric
if (/^\d+$/.test(req.params.id)) {
// this is a request for a book by numeric id
// look up the book numeric id in the database and return the meta
// data about this book
} else {
// not a book id, let next request handler have the request
next();
}
}, (req, res) => {
// must be a book title lookup
// look up the book in the title database and return the id
});

GET request that triggers PATCH request (express) [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
On my express server I have a script which retrieves items through scraping. I want to trigger this script once in a while and push the retrieved items into my database.
My first ideas was to create an endpoint in my API (e.g. /api/scrape-items). The problem is that it would be a GET request responsible for running the script, retrieving the items AND PATCH the items (update) my database. It doesn't seem right to let a GET request do all of that, especially to make a PATCH request, but I can't change the GET request to a POST request either because I have no body.
Can someone help me come up with a better approach? Thanks!
UPDATE: Example of triggering endpoint:
router.get('/scrape-items/', async (req, res) => {
try {
const resultFromScraping = await [
{ id: 1, data: 'updated data' },
{ id: 2, data: 'updated data' }
]
await Promise.all(
resultFromScraping.map(
async item =>
await axios.patch(
`/api/items/${item.id}`,
item.data
)
)
)
} catch (err) {
res.status(500).json({ message: err.message })
}
})
A POST request is perfectly acceptable for uploading content to a database. PATCH is usually reserved for when you are partially updating and item. So if you are just updating stuff in your database with this request, then don't hesitate to use PATCH. If you are completely replacing the resource in the database though (or you require the entire resource in the HTTP request, not just the modified stuff), then I'd recommend using PUT instead.
A GET request would be acceptable as well in this situation if you were returning data to the user.

Soundcloud API /stream endpoint giving 401 error

I'm trying to write a react native app which will stream some tracks from Soundcloud. As a test, I've been playing with the API using python, and I'm able to make requests to resolve the url, pull the playlists/tracks, and everything else I need.
With that said, when making a request to the stream_url of any given track, I get a 401 error.
The current url in question is:
https://api.soundcloud.com/tracks/699691660/stream?client_id=PGBAyVqBYXvDBjeaz3kSsHAMnr1fndq1
I've tried it without the ?client_id..., I have tried replacing the ? with &, I've tried getting another client_id, I've tried it with allow_redirects as both true and false, but nothing seems to work. Any help would be greatly appreciated.
The streamable property of every track is True, so it shouldn't be a permissions issue.
Edit:
After doing a bit of research, I've found a semi-successful workaround. The /stream endpoint of the API is still not working, but if you change your destination endpoint to http://feeds.soundcloud.com/users/soundcloud:users:/sounds.rss, it'll give you an RSS feed that's (mostly) the same as what you'd get by using the tracks or playlists API endpoint.
The link contained therein can be streamed.
Okay, I think I have found a generalized solution that will work for most people. I wish it were easier, but it's the simplest thing I've found yet.
Use API to pull tracks from user. You can use linked_partitioning and the next_href property to gather everything because there's a maximum limit of 200 tracks per call.
Using the data pulled down in the JSON, you can use the permalink_url key to get the same thing you would type into the browser.
Make a request to the permalink_url and access the HTML. You'll need to do some parsing, but the url you'll want will be something to the effect of:
"https://api-v2.soundcloud.com/media/soundcloud:tracks:488625309/c0d9b93d-4a34-4ccf-8e16-7a87cfaa9f79/stream/progressive"
You could probably use a regex to parse this out simply.
Make a request to this url adding ?client_id=... and it'll give you YET ANOTHER url in its return json.
Using the url returned from the previous step, you can link directly to that in the browser, and it'll take you to your track content. I checked on VLC by inputting the link and it streams correctly.
Hopefully this helps some of you out with your developing.
Since I have the same problem, the answer from #Default motivated me to look for a solution. But I did not understand the workaround with the permalink_url in the steps 2 and 3. The easier solution could be:
Fetch for example user track likes using api-v2 endpoint like this:
https://api-v2.soundcloud.com/users/<user_id>/track_likes?client_id=<client_id>
In the response we can finde the needed URL like mentioned from #Default in his answer:
collection: [
{
track: {
media: {
transcodings:[
...
{
url: "https://api-v2.soundcloud.com/media/soundcloud:tracks:713339251/0ab1d60e-e417-4918-b10f-81d572b862dd/stream/progressive"
...
}
]
}
}
...
]
Make request to this URL with client_id as a query param and you get another URL with that you can stream/download the track
Note that the api-v2 is still not public and the request from your client probably will be blocked by CORS.
As mentioned by #user208685 the solution can be a bit simpler by using the SoundCloud API v2:
Obtain the track ID (e.g. using the public API at https://developers.soundcloud.com/docs)
Get JSON from https://api-v2.soundcloud.com/tracks/TRACK_ID?client_id=CLIENT_ID
From JSON parse MP3 progressive stream URL
From stream URL get MP3 file URL
Play media from MP3 file URL
Note: This link is only valid for a limited amount of time and can be regenerated by repeating steps 3. to 5.
Example in node (with node-fetch):
const clientId = 'YOUR_CLIENT_ID';
(async () => {
let response = await fetch(`https://api.soundcloud.com/resolve?url=https://soundcloud.com/d-o-lestrade/gabriel-ananda-maceo-plex-solitary-daze-original-mix&client_id=${clientId}`);
const track = await response.json();
const trackId = track.id;
response = await fetch(`https://api-v2.soundcloud.com/tracks/${trackId}?client_id=${clientId}`);
const trackV2 = await response.json();
const streamUrl = trackV2.media.transcodings.filter(
transcoding => transcoding.format.protocol === 'progressive'
)[0].url;
response = await fetch(`${streamUrl}?client_id=${clientId}`);
const stream = await response.json();
const mp3Url = stream.url;
console.log(mp3Url);
})();
For a similar solution in Python, check this GitHub issue: https://github.com/soundcloud/soundcloud-python/issues/87

Why can't I create a HEAD route in Hapi?

According to the documentation https://hapijs.com/api/16.0.1#route-configuration a route method may not be of the type 'HEAD' but I do not understand why I can not override the behavior.
HEAD routes are automatically created with every GET route you define. Therefore there's very little reason you'd need to define your own.
If you want to optimize your handling of HEAD requests, simply check your GET handler for the method, and if it is head, return an empty response with the correct headers. This is only worth doing for some very expensive GET requests, where you are expecting clients to use HEAD directly.
The main reason not to support it, is that I am expecting very few developers to use this, but it will add an extra lookup for every HEAD request.
This has been already been addressed on Github.
As to further elaborate on #Ankh's response, you can check the request method property to abbreviate the response on the GET handler:
const getHandler = (req, h) => {
// HTTP status 204 -> NO CONTENT
if (req.method as string === 'head') return h.response().code(204)
// continue the GET handler logic here
}