I'm trying to send JSON data with an array to an AWS Lambda function, but I can't parse the array.
In the frontend I'm requesting this way:
const ids = ['long_id1', 'long_id2', 'long_id3'];
const request = await fetch(
'https://ID.execute-api.us-east-1.amazonaws.com/default/endpoint',
{
headers: {
"accept": "application/json, text/plain, */*",
"content-type": "application/json",
},
body: JSON.stringify({
userIds: ids
}),
method: 'POST'
}
)
const response = JSON.parse(await request.text());
In the lambda I have the following code:
exports.handler = async (event) => {
const parsed = JSON.parse(event); //also tried: JSON.parse(JSON.stringify(event)) because I saw someone recommending it
return {
statusCode: 200,
body: JSON.stringify(parsed)
}
}
But I get event.body as a string. For example if I log the event variable I get:
event: {
...,
body: "{\"userIds\":[\"long_id1\",\"long_id2\",\"long_id3\"]}"
}
But, if I try to parse the body, it throws this error:
ERROR SyntaxError: Unexpected token u in JSON at position 0
at JSON.parse (<anonymous>)
at Runtime.exports.handler (/var/task/index.js:11:23)
at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)
2021-08-08T07:43:05.425Z 5feeddb7-6254-405d-b311-42924abc5f4d ERROR SyntaxError: Unexpected token u in JSON at position 0 at JSON.parse (<anonymous>) at Runtime.exports.handler (/var/task/index.js:11:23) at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)
Any idea what am I doing wrong?
Update
Not sure if was some kind of typo but now I'm able to get the data properly. I'm just doing what #Mark B said with the following code in the lambda function:
exports.handler = async (event) => {
const { userIds } = JSON.parse(event.body);
const result = await doSomethingWithUserIds(userIds)
return {
statusCode: 200,
body: JSON.stringify(result)
}
}
Thanks for all the help :)
event is an object. You don't need to parse that into JSON, it's already a JSON object. event.body is a string. You need to parse that property of the event object into JSON.
JSON.parse(event.body)
Not sure if was some kind of typo but now I'm able to get the data properly. I'm just doing what #Mark B said with the following code in the lambda function:
exports.handler = async (event) => {
const { userIds } = JSON.parse(event.body);
const result = await doSomethingWithUserIds(userIds)
return {
statusCode: 200,
body: JSON.stringify(result)
}
}
Thanks for all the help :)
Related
I'm trying to get a user from the MS Graph API.
export const getUser = async (id) => {
//Gives me the token
const token = await getToken(["User.Read", "User.ReadWrite"])
//Appends to headers
const headers = getHeaders(token)
const options = {
method: "GET",
headers: headers
};
return fetch(`https://graph.microsoft.com/v1.0/users/${id}`, options)
}
getUser("MYID").then(response => response.json()).then(response => {
debugger
}).catch((error) => {
debugger
})
Normally I can use .json() to resolve promises from MS Graph, but this call fails with the following error:
Unexpected token < in JSON at position 0
If I remove .json() I can read the response, which gives me the following:
response: Response
body: ReadableStream
bodyUsed: false
headers: Headers {}
ok: true
redirected: false
status: 200
statusText: "OK"
type: "basic"
Given the fact that the body object should be of type ReadableStream, my intuition tells me that I in fact should be able to resolve the promise with .json(), i.e. response.body.json(). However, when I try to do so, I get the following error:
TypeError: response.body.json is not a function at http://localhost:3000/static/js/main.chunk.js:4679:40
I'm pretty unsure what's going on, and naturally I would love if you guys could give me some insights on what's going on. All my other graph "GET" calls encounter no problem when I want to resolve the readableStream.
I believe you are getting response body as html or xml which is why .json() which is used to parse the data to json is throwing exception Unexpected token < in JSON at position 0
I'm using the following code but I'm getting the error "Unexpected token < in JSON at position 0" Why and I getting it and how can I fix this?
async function sendURL(urls) {
const res = await fetch("/ffmpegserver/upload/urls",
{ method: "POST", headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' },
body: JSON.stringify({ urls: urls}) });
const json = await res.json();
return json;
}
window.onload = async () => {
const result = await sendURL([
"http://s5.qhres.com/static/465f1f953f1e6ff2.mp3",
"https://file-examples-com.github.io/uploads/2017/11/file_example_MP3_700KB.mp3"
]);
console.log(result);
}
My money says the response isn't valid json, and possibly HTML instead (hence the <), possibly because the URL is incorrect, meaning that you get the body of a 404 page which might not be accepting application/json.
You can check this with, instead of const json = await res.json();, try:
const body = await res.text();
console.log(body);
it's me again... Sorry for asking so many times a day, but I'm really an idiot.
So basically I'm trying to send a request to the fluxpoint api by using this code:
async welcome(username, avatarurl, background, membercount, icon, backgroundname, filename){
let req = {}
req.username = username;
req.avatar = avatarurl;
if (background == null) {req.background = "#aaaaaa"} else {req.background = background}
if (membercount) req.members = "Member #"+membercount
if (icon) req.icon = icon
if (backgroundname) req.banner = backgroundname
console.log(req)
let usedClient = axios.create({
baseURL: apiUrls[0],
timeout: 5000,
headers: {
'Authorization': this.token,
'Content-Length': 0,
'Content-Type': 'application/json'
},
data: JSON.parse(req),
responseType: 'arraybuffer'
})
console.log(usedClient)
console.log(apiUrls[0]+api1endpoints[1])
let res = await usedClient.get(api1endpoints[1])
return res
}
Here is the code I'm using for testing it:
const fluxpoint = require('./index')
const Client = new fluxpoint.Client("my fluxpoint token")
async function tt(){
let t = await Client.welcome("Koro~ (Baka)#7963", "https://cdn.discordapp.com/avatars/304541381798658048/36806f6ae648b9ebc8303443b0be101c.png", "#FFFFFF", 1, "neko", "space")
console.log(t)
}
tt()
And, here is the error the fluxpoint api sends me:
Failed to parse json, The input does not contain any JSON tokens. Excepted the input to start with a valid JSON token, when isFinalBlock is true. Path: $ | LineNumber: 0 | BytePositionInLine: 0.
I tried everything, but JSON.parse(my data) sends me Unexcepted token o in JSON at position 1
I'm being desesperate and I hope somebody can help me!
It seems you are parsing the raw json.It throws an error
JSON.parse takes string as parameter.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse
And from official doc you cannot use data in get request.
https://github.com/axios/axios#request-config
// `data` is the data to be sent as the request body
// Only applicable for request methods 'PUT', 'POST', and 'PATCH'
// When no `transformRequest` is set, must be of one of the following types:
// - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
// - Browser only: FormData, File, Blob
// - Node only: Stream, Buffer
data: {
firstName: 'Fred'
}
So try passing the data
let res = await usedClient.get(api1endpoints[1],{
params: {
data: res
}
})
I've tested the endpoint it works only if responseType is 'text' or 'stream'
I have been trying to make a login page in reactjs but it's throwing me an error in console like
SyntaxError: Unexpected token r in JSON at position 0 but I got 200 status code in network tab and also I'm getting "redirect" in both response and preview tab under the network tab.
I tried the same code(except it was if(response.ok) this time) with another server of my friend and it successfully redirects it to another page
This is the code that I've been trying: is response.data not correct for reactjs?
performLogin = async () => {
var body = {
password: this.state.password,
email: this.state.email
};
const options = {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json"
},
body: JSON.stringify(body)
};
const url = "/api/authenticate";
try {
const response = await fetch(url, options);
const result = await response.json();
console.log(response); //nothing is showing in console for this statement
if (response.data == "redirect") {
this.props.history.push(`/verifyOtp/${this.state.email}`);
} else {
console.log("login failed");
window.alert("login failed");
}
} catch (error) {
console.error(error);
}
};
edit: I also tried it in postman and it gives "redirect" as response in postman so the api must be working fine
Your problem is in this line
const result = await response.json();
Your response is ok, everything is ok, but when you try to do response.json() and the response from the request isn't a valid json (maybe just a normal text), it will give you that error.
Because response can be a text or a json, you need to do some checking. Where is how to check if response is a json
This is kind of bad because on every request you will need to do this type of checking (transform it to text, try to parse, bla bla...), so What I recommend it you to use something better than fetch.
Axios is very good because it already do that checking.
For your example:
performLogin = async () => {
var body = {
password: this.state.password,
email: this.state.email
};
const options = {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json"
},
body: JSON.stringify(body)
};
const url = "/api/authenticate";
try {
const response = await fetch(url, options); // Fetch the resource
const text = await response.text(); // Parse it as text
const data = JSON.parse(text); // Try to parse it as json
// Do your JSON handling here
} catch(err) {
// This probably means your response is text, do you text handling here
}
}
I am trying to put fetch functions into a separated file, so I can organise these API fetch easily. However, when I try to fetch and return the data, it gives me null or an unexpected json object. Here is part of my src:
//api.js
export async function LoginAPI(username, password) {
const url = baseURL + "/login/";
var params = {username: username, password: md5.hex_md5(password)};
let response = await fetch(url, {
method: 'POST',
headers: {'Accept': 'application/json','Content-Type': 'application/x-www-form-urlencoded'},
body: JSON.stringify(params)
});
return await fetch(url, {
method: 'POST',
headers: header,
body: JSON.stringify(params)
})
.then((res) => res.text())
.then((text) => text.length ? JSON.parse(text) : {})
.catch((error) => {
throw error;
});
};
Here is the another file.
//index.js
var Login = React.createClass({
onPress_login: function() {
var value = this.refs.form.getValue();
if (value) {
result = LoginAPI(value.username, value.password);
console.log(result);
} else {
this.AlertDialog.openDialog();
}
},
render() {
return (
(...)
<Button onPress={this.onPress_login}>
<Text>Login</Text>
</Button>
The fetch is working, it is communicating with the server. However, the console log returns me this at the first place
Promise _45: 0_54: null _65: null _81: 1 __proto__: Object
I am assuming that the result log in the console at the first place is not the await result (the actual response from server, but an object of fetch response). I tried to search out methods online but I can't find any post/blog/article saying how to do fetch as a function call.
Is there any way to do like swift, LoginAPI(username, password, callback: {...}) please?
The problem is that you're are making an async function and not waiting for the response, the you see that kind of console log.
Try this:
result = await LoginAPI(value.username, value.password);
Let me know if this was your problem.