Getting error response = null from api gateway and dynamoDb - node.js

{
"error": "Cannot read property 'playerId' of null"
}
I have created a list lambda function
that passes in a playerId. This playerId is used like so.
export const main = handler(async (event, context) => {
const data = JSON.parse(event.body);
const params = {
TableName: process.env.teamsTable,
ExpressionAttributeValues : {
':playerId' : { S: data.playerId }
},
FilterExpression: "contains (players, :playerId)"
};
try {
const result = await dynamoDb.scan(params);
if (!result.Items) {
throw new Error("Teams not found.");
}
return {
status: 200,
body: result.Items,
};
} catch (e) {
return {
statusCode: 500,
body: JSON.stringify({ error: e.message }),
};}});
I have tested it locally with serverless mocks and it works. Create a call to use it in the FE and hitting this error: {error: "Cannot read property 'playerId' of null"}
error: "Cannot read property 'playerId' of null", also hit it through API gateway and hitting same.
frontEnd call -
const endpoint = "/teams";
console.log(playerId);
try {
const response = await API.get(amplifyAPIName, endpoint, {
body: playerId
});
return response;
} catch {
return [];
}
}
help

Answer: I was using the get method instead of post. I am passing playerId as a filter expression in aws. By changing it to post I was able to receive my results.

Related

AWS SQS on Lambda throws argument must be ArrayBuffer when sending message using SQSClient

I am trying to send a message to SQS using a lambda node 16 TypeScript.
If I run it locally the code works. But if I run it externally I get this error:
TypeError: The "input" Received type object ([object Object])
//full message is actually part of the response body:
//"{\"message\":\"Error: failed to schedule userflow test\\nTypeError: The \\\"input\\\" argument must be ArrayBuffer. Received type object ([object Object])\"}"
The function is quite simple:
import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
import { SQSClient, SendMessageCommand } from "#aws-sdk/client-sqs";
export const lambdaHandler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
let response: APIGatewayProxyResult;
let messageBody: string;
if (!event.body) {
response = {
statusCode: 500,
body: JSON.stringify({
message: 'No Target Information Found',
}),
};
return response;
} else {
response = {
statusCode: 200,
body: JSON.stringify({
message: 'hello world',
}),
};
messageBody = event.body;
}
const client = new SQSClient({ region: "us-east-1" });
const params = {
MessageBody: messageBody,
QueueUrl: "https://sqs.us-east-1.amazonaws.com/41111111119/scheduled-userflows"
}
const command = new SendMessageCommand(params);
try {
await client.send(command);
} catch (error) {
response = {
statusCode: 500,
body: JSON.stringify({
message: 'Error: failed to schedule userflow test\n' + error,
}),
};
} finally {
return response;
}
};
What does that mean?
Why does this only happen on Lambda and not locally?
This is with the purpose of achieving this: How can I execute a puppeteer script in the cloud as a single task?
The MessageBody property in the input object should be a string, not an object. You can convert your object to a string before passing it to the MessageBody property.
const params = {
MessageBody: JSON.stringify(messageBody),
QueueUrl: "https://sqs.us-east-1.amazonaws.com/41111111119/scheduled-userflows"
}

React Expo: FileSystem.uploadAsync not sending request to the server instead throwing error

I am developing an app on react expo, and using Filesystem.uploadasync for file uploading and other data. But filesystem is not sending request to the server and throwing error "
[Unhandled promise rejection: TypeError: undefined is not an object (evaluating '_context.t0.response.data')]". Below is my code
const addRequest = async (values, url) => {
try {
const user = await getData('user');
if (user != null) {
const token = user.Token;
const requestBody = {Branches: values.Branches, Color: values.Color, ImageInPOS: values.ImageInPOS, Name: values.Name, VisibilityInPOS: values.ImageInPOS}
console.log(requestBody);
console.log(values.Image.uri);
const result = await FileSystem.uploadAsync(`${BaseUrl}/${url}`, values.Image.uri, {
fieldName: 'Image',
httpMethod: "POST",
uploadType: FileSystemUploadType.MULTIPART,
parameters: requestBody,
headers: {
authorization: `Bearer ${token}`,
}
})
console.log(result);
return {
msg: result.data.msg,
status: result.status
};
}
else {
return;
}
}
catch (err) {
return {
msg: err.response.data.msg ? err.response.data.msg : "Something went wrong, Try Again",
status: err.response.status ? err.response.status : 500
};
}
}
I have cross checked my url, all imports but could not figure out what is going wrong.

send body with "GET" method in axios

Is there anyway to send body with GET method in axios? because in postman it is possible. My backend code as below:
I'm using express.js + sequelize
const c_p_get_all = async (req, res) => {
const { category } = req.body;
const sql = `select p.id, p.p_image, p.p_name, p.p_desc, p.p_prize, p.p_size, c.c_name, cl.cl_name
from products as p
inner join collections as cl on cl.id = p.p_collection_id
inner join categories as c on c.id = cl.cl_category_id
where c.c_name = ?
order by p."createdAt" desc;`;
try {
const getData = await Product.sequelize.query(sql, {
replacements: [category],
});
if (getData[0] != "") {
res.status(200).send({
s: 1,
message: "success retrive all products",
data: getData[0],
});
} else {
res.status(404).send({
s: 0,
message: "data not found",
});
}
} catch (err) {
res.status(500).send({
message: err,
});
}
};
My Frontend with react.js + axios
const test = "woman";
axios({
headers: {
"content-type": "application/json",
},
method: "GET",
url: "http://localhost:3001/api/v1/product",
data: { category: test },
})
.then((value) => console.log(value))
.catch((error) => console.log(error.response));
It always goes to status 404, but in postman its working, I've tried to search this problem, but no clue. So is there anyway to do it in axios, or should I change my backend to POST method or change req.body to req.query?
I changed to query parameters and it worked

Using React, NodeJS, and Postgres: Having trouble being able to delete and updating todos

I am creating simple todo app with postgre and react.
The server side the delete and update are defined as below.
app.put("/todos/:id", async (req, res) => {
try {
const { id } = req.params;
const { description } = req.body;
const updateTodo = await pool.query(
"update todo set description = $1 where todo_id = $2",
[description, id]
);
res.json("todo updated !!");
} catch (error) {
console.error(error.message);
}
});
// delete todo
app.delete("/todos/:id", async (req, res) => {
try {
const { id } = req.params;
const deleteTodo = await pool.query("delete from todo where todo_id = $1", [
id,
]);
res.json("todo deleted !!");
} catch (error) {
console.error(error.message);
}
});
On the front end (React) this is how I am calling the update and delete
const updateDescription = async () => {
try {
handleClose();
const body = { description };
const response = fetch(`http://localhost:3000/${todo.todo_id}`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
});
console.log(response);
} catch (error) {
console.log(error.message);
}
};
Delete todo is in the other component.
const deleteTodo = async (id) => {
try {
const deleteTodo = await fetch(`http://localhost:3000/${id}`, {
method: "DELETE ",
});
console.log(deleteTodo);
setTodods(todos.filter((todo) => todo.todo_id !== id));
} catch (error) {
console.log(error.message);
}
};
So when I am doing delete or put request its not updating it in the DB.
On the browser console I am getting this error.
Failed to execute 'fetch' on 'Window': 'DELETE ' is not a valid HTTP method.
Edited
Response {type: "cors", url: "http://localhost:3000/3", redirected: false, status: 404, ok: false, …}
body: (...)
bodyUsed: false
headers: Headers {}
ok: false
redirected: false
status: 404
statusText: "Not Found"
type: "cors"
url: "http://localhost:3000/3"
__proto__: Response
For insert todo its working but for delete and put request its not updating in the database.
So can somebody tell me whats going wrong here ?
There is a space after DELETE, correct it should work properly. Even if its a simple todo App, its always good practice to create an enum or const when we are dealing with fixed string, i.e., we know the string would not change so that we can have consistency and skip over these kind of issues.
const METHOD = {
GET: "GET",
PUT: "PUT",
POST: "POST",
DELETE: "DELETE"
};

Webhook Error: Unable to extract timestamp and signatures from header - Netlify Functions and Stripe

I am trying to console log the Stripe customerID once the checkout.session.completed event is complete. but I am getting this 400 status code error "Unable to extract timestamp and signatures from header". I can't seem to figure out a solution to get the Stripe customer ID to console log.
Any help or pointers are appreciated. Here is my code:
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
exports.handler = async ({ body, headers }) => {
try {
const stripeEvent = stripe.webhooks.constructEvent(
body,
headers['stripe-signature'],
process.env.STRIPE_WEBHOOK_SECRET
);
if (stripeEvent.type === 'checkout.session.completed') {
const eventObject = stripeEvent.data.object;
const customerID = eventObject.customer;
console.log(customerID);
console.log(headers);
}
return {
statusCode: 200,
body: JSON.stringify(customerID),
};
} catch (err) {
console.log(`Stripe webhook failed with ${err}`);
return {
statusCode: 400,
body: `Webhook Error: ${err.message}`,
};
}
};
When I console log the headers as suggested from a comment in get this in the terminal:
I can now see the customer ID (cus_JOqbW95ulF3zx0) in the terminal, but what do I need to log it as customerID? When the terminal is saying customerID is not defined.
I was able to figure it out. My return after the IF statement was the reason for the 400 status code error. the customerID shows up in the console and I changed the return in the body stats code to a string "success".
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
exports.handler = async ({ body, headers }) => {
try {
const stripeEvent = stripe.webhooks.constructEvent(
body,
headers['stripe-signature'],
process.env.STRIPE_WEBHOOK_SECRET
);
if (stripeEvent.type === 'checkout.session.completed') {
const eventObject = stripeEvent.data.object;
const customerID = eventObject.customer;
console.log(customerID);
}
return {
statusCode: 200,
body: 'success',
};
} catch (err) {
console.log(`Stripe webhook failed with ${err}`);
return {
statusCode: 400,
body: `Webhook Error: ${err.message}`,
};
}
};

Resources