Zomato API not working - ReactJs - javascript

I'm having a hard time trying to make a basic zomato api request work, in reactjs.
The api documentation looks so simple. I'm doing a basic GET request to categories: https://developers.zomato.com/documentation#!/common/categories
And here's how my ReactJS function looks like:
componentDidMount() {
// A previous request for london restaurants
// axios.get('https://developers.zomato.com/api/v2.1/geocode?
lat=51.5138&lon=0.0984')
axios.get('https://developers.zomato.com/api/v2.1/categories')
.then(res => {
console.log(res.data);
this.setState(
{ places: res.data});
});
}
However, I keep getting this response when I hit any api url, in the browser. Or via insomnia.
{
"code": 403,
"status": "Forbidden",
"message": "Invalid API Key"
}
I know it says invalid API. But I've gotten these URLs after loggin in and applying any API key in Zomato's developer portal. Can't find any intructions to figure where I've gone wrong...
Thanks,
Reena.

i got it, the answer was this:
const config = { headers: {'user-key': 'MY KEY HERE'} };
enter code here
axios.get('developers.zomato.com/api/v2.1/…;, config) .then(res => {
console.log(res.data.collections); this.setState( { places:
res.data.collections }); });
thank you all.

Pass the API_Key from Headers you'll get the response data.
axios({
method: "GET",
url: "https://developers.zomato.com/api/v2.1/search",
headers: {
"user-key": "b8cc3b8b0a85afed047f030fb52dc15f",
"content-type": "application/json"
}
})
.then(response => {
console.log(response.data.restaurants[0].restaurant.name);
})
.catch(error => {
console.log(error);
});

You need to set this key this in the request header.
X-Zomato-API-Key:
Sample request:
curl -X GET --header "Accept: application/json" --header "X-Zomato-API-Key: <YOUR_API_KEY>" "https://developers.zomato.com/api/v2.1/categories"
Hope this will help you.

Seems you are missing user-key parameter and its value. For example, the URL should be something like:
https://developers.zomato.com/api/v2.1/categories?user-key=<your API key>

Related

Feedly API is returning session expired instead of letting me access the API from local node environment

Using feedlys api with a node wrapper suggested from feedly to access its api. I am not getting successful logins. I have scoured the docs and any resources available and cannot find any answers so I'm reaching out to the stack overflow community to see if anyone has had experience with this platform.
I tried clearing the cache. I've tried using the fetch api instead of using the node wrapper I am trying to implement.
I installed the node package 'feedly'.
added this code to my server:
const Feedly = require('feedly')
const f = new Feedly({
client_id: 'client_id here',
client_secret: 'client_secret here',
base: 'https://cloud.feedly.com/v3/collections/',
port: 8080
})
async function feedlyStream() {
const results = await f.reads()
return console.log('results', results)
}
feedlyStream();
It does take me to a page to log in, presumably this is the auth so then i can retrieve data.
I'm not a backend user and primarily front end so performing the task this way is new to me.
When i run nodemon ./server.js from the console, it takes me to a login page, like that of feedlys website but then I get the error 'session expired'. There is no other errors, not in the console etc.
I can get retrieve information when working with insomnia to test the api endpoints, with the same exact info as above plus a bearer token.
Here is the fetch version i have tried with is very similar to that of the insomnia input.
const URL = 'https://cloud.feedly.com/v3/collections/'
const proxyurl = "https://cors-anywhere.herokuapp.com/";
window.onload = () => {
fetch(proxyurl + URL, {
credentials: 'same-origin',
Accept: 'application/json',
headers:
{
'Authorization': 'Bearer TOKEN GOES HERE',
'Access-Control-Allow-Origin': 'include',
'Content-Type': 'application/json',
"client_id": "client_id here",
"method": "GET",
"client_secret": "client_secret here",
}
})
.then(function (data) {
console.log('data from api', data.body);
const here = document.getElementById("here")
const bodyText = () => {
if (data.body == null) {
return "Nope, it's null"
}
return data.body;
}
here.innerHTML = bodyText();
})
}
This is what i receive from the console log above
data from api ReadableStreamlocked: false__proto__: ReadableStream
Any help will be greatly appreciated. Thank you.
quite simply i was missing part of the fetch. I needed to transform the response into JSON. Not use to fetch or apis still and this was an obvious but annoying one.
"method": "GET",
"client_secret": "client_secret here",
}
})
.then(res => res.json();) // this is what i needed to add in :)
.then(function (data) {
console.log('data from api', data.body);

Axios - DELETE Request With Request Body and Headers?

I'm using Axios while programming in ReactJS and I pretend to send a DELETE request to my server.
To do so I need the headers:
headers: {
'Authorization': ...
}
and the body is composed of
var payload = {
"username": ..
}
I've been searching in the inter webs and only found that the DELETE method requires a "param" and accepts no "data".
I've been trying to send it like so:
axios.delete(URL, payload, header);
or even
axios.delete(URL, {params: payload}, header);
But nothing seems to work...
Can someone tell me if it's possible (I presume it is) to send a DELETE request with both headers and body and how to do so?
So after a number of tries, I found it working.
Please follow the order sequence it's very important else it won't work
axios.delete(URL, {
headers: {
Authorization: authorizationToken
},
data: {
source: source
}
});
axios.delete does supports both request body and headers.
It accepts two parameters: url and optional config. You can use config.data to set the request body and headers as follows:
axios.delete(url, { data: { foo: "bar" }, headers: { "Authorization": "***" } });
See here - https://github.com/axios/axios/issues/897
Here is a brief summary of the formats required to send various http verbs with axios:
GET: Two ways
First method
axios.get('/user?ID=12345')
.then(function (response) {
// Do something
})
Second method
axios.get('/user', {
params: {
ID: 12345
}
})
.then(function (response) {
// Do something
})
The two above are equivalent. Observe the params keyword in the second method.
POST and PATCH
axios.post('any-url', payload).then(
// payload is the body of the request
// Do something
)
axios.patch('any-url', payload).then(
// payload is the body of the request
// Do something
)
DELETE
axios.delete('url', { data: payload }).then(
// Observe the data keyword this time. Very important
// payload is the request body
// Do something
)
Key take aways
get requests optionally need a params key to properly set query parameters
delete requests with a body need it to be set under a data key
axios.delete is passed a url and an optional configuration.
axios.delete(url[, config])
The fields available to the configuration can include the headers.
This makes it so that the API call can be written as:
const headers = {
'Authorization': 'Bearer paperboy'
}
const data = {
foo: 'bar'
}
axios.delete('https://foo.svc/resource', {headers, data})
For those who tried everything above and still don't see the payload with the request - make sure you have:
"axios": "^0.21.1" (not 0.20.0)
Then, the above solutions work
axios.delete("URL", {
headers: {
Authorization: `Bearer ${token}`,
},
data: {
var1: "var1",
var2: "var2"
},
})
You can access the payload with
req.body.var1, req.body.var2
Here's the issue:
https://github.com/axios/axios/issues/3335
For Delete, you will need to do as per the following
axios.delete("/<your endpoint>", { data:<"payload object">})
It worked for me.
I had the same issue I solved it like that:
axios.delete(url, {data:{username:"user", password:"pass"}, headers:{Authorization: "token"}})
Actually, axios.delete supports a request body.
It accepts two parameters: a URL and an optional config. That is...
axios.delete(url: string, config?: AxiosRequestConfig | undefined)
You can do the following to set the response body for the delete request:
let config = {
headers: {
Authorization: authToken
},
data: { //! Take note of the `data` keyword. This is the request body.
key: value,
... //! more `key: value` pairs as desired.
}
}
axios.delete(url, config)
I hope this helps someone!
If we have:
myData = { field1: val1, field2: val2 }
We could transform the data (JSON) into a string then send it, as a parameter, toward the backend:
axios.delete("http://localhost:[YOUR PORT]/api/delete/" + JSON.stringify(myData),
{ headers: { 'authorization': localStorage.getItem('token') } }
)
In the server side, we get our object back:
app.delete("/api/delete/:dataFromFrontEnd", requireAuth, (req, res) => {
// we could get our object back:
const myData = JSON.parse(req.params.dataFromFrontEnd)
})
Note: the answer from "x4wiz" on Feb 14 at 15:49 is more accurate to the question than mine! My solution is without the "body" (it could be helpful in some situation...)
Update: my solution is NOT working when the object has the weight of 540 Bytes (15*UUIDv4) and more (please, check the documentation for the exact value). The solution of "x4wiz" (and many others above) is way better. So, why not delete my answer? Because, it works, but mostly, it brings me most of my Stackoverflow's reputation ;-)
i found a way that's works:
axios
.delete(URL, {
params: { id: 'IDDataBase'},
headers: {
token: 'TOKEN',
},
})
.then(function (response) {
})
.catch(function (error) {
console.log(error);
});
I hope this work for you too.
To send an HTTP DELETE with some headers via axios I've done this:
const deleteUrl = "http//foo.bar.baz";
const httpReqHeaders = {
'Authorization': token,
'Content-Type': 'application/json'
};
// check the structure here: https://github.com/axios/axios#request-config
const axiosConfigObject = {headers: httpReqHeaders};
axios.delete(deleteUrl, axiosConfigObject);
The axios syntax for different HTTP verbs (GET, POST, PUT, DELETE) is tricky because sometimes the 2nd parameter is supposed to be the HTTP body, some other times (when it might not be needed) you just pass the headers as the 2nd parameter.
However let's say you need to send an HTTP POST request without an HTTP body, then you need to pass undefined as the 2nd parameter.
Bare in mind that according to the definition of the configuration object (https://github.com/axios/axios#request-config) you can still pass an HTTP body in the HTTP call via the data field when calling axios.delete, however for the HTTP DELETE verb it will be ignored.
This confusion between the 2nd parameter being sometimes the HTTP body and some other time the whole config object for axios is due to how the HTTP rules have been implemented. Sometimes an HTTP body is not needed for an HTTP call to be considered valid.
For Axios DELETE Request, you need to include request payload and headers like this under one JSON object:
axios.delete(URL, {
headers: {
'Authorization': ...
},
data: {
"username": ...
}
})
Why can't I do it easily as I do similar to POST requests?
Looking at the Axios documentation, we see that the methods for .get, .post... have a different signature:
axios.get(url[, config])
axios.delete(url[, config])
axios.head(url[, config])
axios.options(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])
Notice how only post, patch and put have the data parameter. This is because these methods are the ones that usually include a body.
Looking at RFC7231, we see that a DELETE request is not expected to have a body; if you include a body, what it will mean is not defined in the spec, and servers are not expected to understand it.
A payload within a DELETE request message has no defined semantics; sending a payload body on a DELETE request might cause some existing implementations to reject the request.
(From the 5th paragraph here).
In this case, if you are also in control of the server, you could decide to accept this body in the request and give it whatever semantics you want. May be you are working with somebody else's server, and they expect this body.
Because DELETE requests with bodies are not defined in the specs, and because they're not common, Axios didn't include them in those method aliases. But, because they're possible, you can do it, just takes a bit more effort.
I'd argue that it would be more conventional to include the information on the url, so you'd do:
axios.delete(
`https://example.com/user/${encodeURIComponent(username}`,
{ headers: ... }
)
or, if you want to be able to delete the user using different criteria (sometimes by username, or by email, or by id...)
axios.delete(
`https://example.com/user?username=${encodeURIComponent(username)}`,
{ headers: ... }
)
Not realated to axios but might help people tackle the problem they are looking for. PHP doesn't parse post data when preforming a delete call. Axios delete can send body content with a request.
example:
//post example
let url = 'http://local.test/test/test.php';
let formData = new FormData();
formData.append('asdf', 'asdf');
formData.append('test', 'test');
axios({
url: url,
method: 'post',
data: formData,
}).then(function (response) {
console.log(response);
})
result: $_POST Array
(
[asdf] => asdf
[test] => test
)
// delete example
axios({
url: url,
method: 'delete',
data: formData,
}).then(function (response) {
console.log(response);
})
result: $_POST Array
(
)
to get post data on delete call in php use:
file_get_contents('php://input');
axios.post('/myentity/839', {
_method: 'DELETE'
})
.then( response => {
//handle success
})
.catch( error => {
//handle failure
});
Thanks to:
https://www.mikehealy.com.au/deleting-with-axios-and-laravel/
I encountered the same problem...
I solved it by creating a custom axios instance. and using that to make a authenticated delete request..
const token = localStorage.getItem('token');
const request = axios.create({
headers: {
Authorization: token
}
});
await request.delete('<your route>, { data: { <your data> }});
I tried all of the above which did not work for me. I ended up just going with PUT (inspiration found here) and just changed my server side logic to perform a delete on this url call. (django rest framework function override).
e.g.
.put(`http://127.0.0.1:8006/api/updatetoken/20`, bayst)
.then((response) => response.data)
.catch((error) => { throw error.response.data; });
Use {data: {key: value}} JSON object, the example code snippet is given below:
// Frontend Code
axios.delete(`URL`, {
data: {id: "abcd", info: "abcd"},
})
.then(res => {
console.log(res);
});
// Backend Code (express.js)
app.delete("URL", (req, res) => {
const id = req.body.id;
const info = req.body.info;
db.query("DELETE FROM abc_table WHERE id=? AND info=?;", [id, info],
(err, result) => {
if (err) console.log(err);
else res.send(result);
}
);
});
Axios DELETE request does supports similar what POST request does, but comes in different formats.
DELETE request payload sample code:
axios.delete(url, { data: { hello: "world" }, headers: { "Authorization": "Bearer_token_here" } });
POST request payload sample code:
axios.post(url, { hello: "world" }, { headers: { "Authorization": "Bearer_token_here" } });
Noticed that { hello: "world" } is configured in different ways, but both performs same functions.
this code is generated from post man and it's perfectly work for delete api request with body.
var data = JSON.stringify({"profile":"false","cover":"true"});
var config = {
method: 'delete',
url: 'https://api.fox.com/dev/user/image',
headers: {
'Authorization': 'Bearer token',
},
data : data
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});

You are not authorized for this operation. Invalid access token DialogFlow v2

I am trying to use DialogFlow v2 endpoint but for some reason I am getting not authorized message, eventhou I am able to generate access token using the following command:
Initially I am running this to authorize the service for my local machine to be able to authorize to the service: gcloud auth activate-service-account --key-file=<service-account-key-file.json> then I get access token by following command: gcloud auth print-access-token and this access token I am attaching on the following code:
fetch(configs.baseUrl + "query?v=20150910", {
body: JSON.stringify({query: text, lang: "en", sessionId: "somerandomthing"}),
headers: {
'content-type': 'application/json',
"Authorization": "Bearer " + accessToken,
},
method: 'POST',
})
.then(response => response.json())
.then(data => {
console.log(data.result.fulfillment.speech);
return data.result.fulfillment.speech;
})
.catch(error => console.error(error))
I dont know if this is the right way to achieve a communication with DialogFlow V2?
Please if you could let me know what I am doing wrong and why I it says I am not authorised since I am authorizing by the above commands and been able to get access token!
Edit:
After few changes my code finally looks like this:
fetch("https://dialogflow.googleapis.com/v2beta1/projects/xxx/agent/sessions/xxx/:detectIntent", {
body: JSON.stringify({queryInput: "Hello"}),
headers: {
'content-type': 'application/json',
"Authorization": "Bearer xxxx",
},
method: 'POST',
})
.then(response => response.json())
.then(data => {
console.log(data.result.fulfillment.speech);
return data.result.fulfillment.speech;
})
.catch(error => console.error(error))
and the new error message I get is:
{
"error": {
"code": 400,
"message": "Invalid value at 'query_input' (type.googleapis.com/google.cloud.dialogflow.v2beta1.QueryInput), \"Hello\"",
"status": "INVALID_ARGUMENT",
"details": [
{
"#type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"field": "query_input",
"description": "Invalid value at 'query_input' (type.googleapis.com/google.cloud.dialogflow.v2beta1.QueryInput), \"Saanko yhteystiedot?\""
}
]
}
]
}
}
You don't show the baseUrl you're using, but that looks like the V1 API rather than the V2 API. You should migrate your code to V2.
Keep in mind, also, that the access token expires, so you will need to generate a new one periodically. You cannot request a "long lived" token (this is considered insecure), but should have your code call gcloud auth print-access-token (or use a library to do the same thing) before the previous one expires.
Update based on your code once you've moved it to V2:
The queryInput parameter doesn't take a string directly. It must be set to a QueryInput object. This is an enum, so can only have one of the fields specified set. It looks like you want the text field which requires a TextInput object.
So your body parameter might be setup something like this:
var body = {
queryInput: {
text: {
text: "Hello",
language: "en-US"
}
}
};
var bodyStr = JSON.stringify(body);
and then set in your request() options.
Because you have put wrong URL in your project.
Open below image and see which URL use for posturl in your project
https://i.stack.imgur.com/3ym9n.png

Axios stripe issues. "invalid_request_error"

I am at my wits end! I am trying to create a customer via the stripe api. Using their example with curl i have no problems.
Here is their example:
curl https://api.stripe.com/v1/customers \
-u sk_test_apikey: \
-d description="Customer for zoey.brown#example.com" \
-d source=tok_visa
It is when i try to do this with axios that i get an error "invalid_request_error" because it isn't properly parsing my data. Here's what i've got:
export const registerNewUser = async (firstName, lastName, email, password) => {
let config = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': `Bearer ${stripeTestApiKey}`
}
}
let data = {
email: `${email}`,
description: `Customer account for ${email}`
}
await axios.post(stripeCustomerUri, data, config)
.then(res => {
console.log("DEBUG-axios.post--res: ", res)
})
.catch(err => {
console.log(JSON.stringify(err, null, 2))
})
}
and in my console i see that stripe isn't receiving my data in the correct manner. Here's the (useful part of my) response json:
"response": {
"data": {
"error": {
"type": "invalid_request_error",
"message": "Received unknown parameter: {\"email\":\"joe#blow.com\",\"description\":\"Customer account for joe#blow.com\"}", "param": "{\"email\":\"joe#blow.com\",\"description\":\"Customer account for joe#blow.com\"}" } },
Judging by all of my other attempts and this example error, I am not passing my data in the correct format... However, when i pass -d to my curl command everything works as expected... If I send an empty string as data it works as well...
does anyone have an idea why / how this is? How is the "data" object via curl differ from my javascript data object?
The problem was that axios uses application/json content type by default and the stripe api requires form-url-encoded... this requires parsing the data object with a library like querystring before passing through to the stripe api... hope this helps someone!

GitHub API - Comment on Gist returns 404

After following the documentation on GitHub's API, I got stuck on submitting a comment for a gist, the following code always returns 404, and the same call made in Postman too.
My JavaScript code as follows:
const config = {
method: 'POST',
headers: {
'Authorization': credentials.authorizationHeader,
'Content-Type': 'application/vnd.github.v3.text+json'
},
body: { "body": JSON.stringify(comment) }
};
fetch(`https://api.github.com/gists/${gistId}/comments/`, config)
.then(res => {
if (res.ok) {
dispatch(getGistDetails(gistId, credentials));
dispatch({ type: SUBMIT_COMMENT_SUCCESS });
} else {
ToastAndroid.show('An error ocurred, please try again.', ToastAndroid.SHORT);
console.log(res);
dispatch({ type: SUBMIT_COMMENT_FAIL });
}
})
.catch(err => console.log(err));
Credentials I'm getting via OAuth:
accessToken: "redacted"
authorizationHeader:"bearer redacted"
clientID:"redacted"
idToken:null
scopes:"gist"
type:"bearer"
I tried changing the authorizationHeader to token <oauth_token, but still no success.
Thanks in advance.
Looks like you have some non standard characters in your GIST ID that are not even visible and I can't even get your link to work ( or is it private? )
Turns out I was overcomplicating, as getting a gist's details through the API also nets you a comments_url field with the correct url, so no need to splice strings, falling into the very strange issue mentioned by #Zilvinas below. Also, a minor adjustment in the body to
const body = { body: comment }
const config = {
method: 'POST',
headers: {
'Authorization': credentials.authorizationHeader,
'Content-Type': 'application/vnd.github.v3.text+json'
},
body: JSON.stringify(body)
};
fixed the subsequent Problems parsing JSON error I got.

Categories