POST returns undefined with Cloud Function - javascript

I'm implementing Stripe for React Native and I'm trying to send the customerId to my Cloud Function using POST, but when I execute the code it returns in the console.log undefined
Cloud Function (Firebase)
exports.addCardForExistingCustomer = functions.https.onRequest(async (request, response) => {
let id = await request.body.customer_id
response.send({
result: id
})
});
Client side
const fetchPaymentSheetParams = async () => {
const response = await fetch(`${API_URL}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ customer_id: customerId })
});
const { result } = await response.json();
console.log(result)
};

Related

React / Node - PayPal can't capture a new subscription

I wan't to capture a new paypal subscription from frontend in my backend and give response with the needed data for mongodb.
If I add a body with capture_type: 'OUTSTANDING_BALANCE' (I found that in the manual) I'm getting this error.
So I'm not sure either it's just a wrong body or i totally mess up something else in the backend but so far I can't capture the subscription even so I get a subscription Id from
createSubscription Controller
PayPalScriptProvider
<PayPalScriptProvider options={initialOptions}>
<PayPalSubscriptionButton/>
</PayPalScriptProvider>
PayPal Button
{isPending ? <LoadingMedium /> : null}
<PayPalButtons
createSubscription={(data, actions) => {
return axios
.post(
'/api/subscription',
)
.then((response) => {
return response.data.id;
});
}}
onApprove={(data, actions) => {
axios
.post(`/api/subscription/${data.subscriptionID}/capture`)
.then(() => {
axios
.patch(
`/api/activesubscription`,
{
id: activeSub[0]?._id,
subscriptionID: data.subscriptionID,
}
)
});
});
}}
/>
Route for createSubscription
router.route('/subscription').post(async (req, res) => {
const searchPlan = await SubscriptionAmount.find();
console.log(searchPlan[0]?.subscriptionAmount);
const subscription = await paypalFee.createSubscription(
searchPlan[0]?.subscriptionAmount
);
res.json(subscription);
});
Router for onApprove
router.post('/subscription/:subscriptionID/capture', async (req, res) => {
const { subscriptionID } = req.params;
console.log('subscriptionID', subscriptionID);
const captureData = await paypalFee.captureSubscription(subscriptionID);
console.log('captureData', captureData);
res.json(captureData);
});
createSubscription Controller
async function createSubscription(planId) {
const accessToken = await generateAccessToken();
const url = `${base}/v1/billing/subscriptions`;
const response = await fetch(url, {
method: 'post',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${accessToken}`,
},
body: JSON.stringify({
intent: 'subscription',
plan_id: planId,
}),
});
const data = await response.json();
console.log('data', data);
return data;
}
captureSubscription Controller
async function captureSubscription(subscriptionId) {
const accessToken = await generateAccessToken();
const url = `${base}/v1/billing/subscriptions/${subscriptionId}/capture`;
const response = await fetch(url, {
method: 'post',
body: JSON.stringify({
// capture_type: 'OUTSTANDING_BALANCE',
}),
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${accessToken}`,
},
});
const data = await response.json();
console.log('data', data);
return data;
}
I'm getting this logs for my data in captureSubscription if I do not pass a body in my captureSubscription Controller:
captureData {
name: 'INVALID_REQUEST',
message: 'Request is not well-formed, syntactically incorrect, or violates schema.',
details: [
{
location: 'body',
issue: 'MISSING_REQUEST_BODY',
description: 'Request body is missing.'
}
]
}
With body I'm getting this error
captureData {
name: 'UNPROCESSABLE_ENTITY',
message: 'The requested action could not be performed, semantically incorrect, or failed business validation.',
details: [
{
issue: 'ZERO_OUTSTANDING_BALANCE',
description: 'Current outstanding balance should be greater than zero.'
}
],
}
ZERO_OUTSTANDING_BALANCE
There is no outstanding balance to capture. An outstanding balance occurs when payments are missed due to failures.
For ordinary (non-outstanding) subscription payments, no captures can be triggered. Subscriptions will capture automatically on the schedule you specify in the plan, that is the point of subscriptions.

MERN pagination and filtering in same controller

How to do pagination and filtering at the backend in the same controller?
Filter service:-
const filterPosts = async (filterData, token) => {
const config = {
headers: {
Authorization: `Bearer ${token}`,
},
data: {
filterData,
},
};
const response = await axios.get(API_URL, config);
return response.data;
}
Route:-
router.route("/").get(protect, getPosts);
Controller:-
I cant seem to send the filterData from service to this controller, how to achieve it?
const getPosts = asyncHandler(async (req, res) => {
console.log("filter data:- ", req.body); // This Part is undefined.
//pagination
const PAGE_SIZE = 6;
const PAGE = parseInt(req.query.page || "0");
const total = await Post.countDocuments({ user: req.user.id });
const AllPosts = await Post.find({ user: req.user.id })
.limit(PAGE_SIZE)
.skip(PAGE_SIZE * PAGE)
.sort({ createdAt: -1 });
const totalPages = Math.ceil(total / PAGE_SIZE);
res.status(200).json({ totalPages, Allposts });
});
console.log("filter data:- ", req.body); // This Part is undefined.
You can send this data using config.params in Get request or use Post request if you want to use config.data.
Sometimes XHR / Fetch do not allow payload in Get request.
As per this axios doc, sending data as request body is only applicable for request methods PUT, POST, DELETE , and PATCH.
You can also refer to this issue for reference : Link
const filterPosts = async (filterData, token) => {
const config = {
headers: {
Authorization: `Bearer ${token}`,
},
params: {
filterData,
},
};
const response = await axios.get(API_URL, config);
return response.data;
}

How do I return an item from an async funtion

Ive been looking into trying to get information from websites using fetch. Trying async/await was my first solution, and so far it has been going well. Getting the information I needed was a breeze, but trying to retrieve that data in main is my problem. Const data in my main function even with the await tag only returns an undefined object. How can I get the data that I have in the function into my main
import React from "react";
import {
WASTEMANAGEMENT_USERNAME,
WASTEMANAGEMENT_PASSWORD,
WASTEMANAGEMENT_APIKEY_AUTH,
WASTEMANAGEMENT_APIKEY_CUSTID,
WASTEMANAGEMENT_APIKEY_DATA,
} from "#env";
async function login() {
let response = await fetch("https://rest-api.wm.com/user/authenticate", {
method: "POST",
headers: {
"content-type": "application/json",
apikey: WASTEMANAGEMENT_APIKEY_AUTH,
},
body: JSON.stringify({
username: WASTEMANAGEMENT_USERNAME,
password: WASTEMANAGEMENT_PASSWORD,
locale: "en_US",
}),
});
let res = await response.json();
const id = res.data.id;
const access_token = res.data.access_token;
response = await fetch(
`https://rest-api.wm.com/authorize/user/${id}/accounts?lang=en_US`,
{
method: "GET",
headers: {
oktatoken: access_token,
apikey: WASTEMANAGEMENT_APIKEY_CUSTID,
},
}
);
res = await response.json();
const custId = res.data.linkedAccounts[0].custAccountId;
response = await fetch(
`https://rest-api.wm.com/account/${custId}/invoice?userId=${id}`,
{
method: "GET",
headers: {
apikey: WASTEMANAGEMENT_APIKEY_DATA,
token: access_token,
},
}
);
res = await response.json();
res.body.balances.filter((item) => {
if (item.type === "Current") {
console.log(item);
return item;
}
});
}
const WasteManagementLogin = async () => {
const data = await login();
console.log(data);
};
export default WasteManagementLogin;

Promise.all() with dynamically sized array of requests using await

I'm new to JavaScript and Promises. I need to send an array of requests using Promise.all and await. Unfortunately, I do not know the size of the array, so it needs to be dynamic. The array would be requests. Ex:
let arrayOfApiCreateRecords = [];
arrayOfApiCreateRecords.push(apiCreateRecords(req, { clientHeaders: headers, record }));
let responses = await Promise.all( arrayOfApiCreateRecords );
I tried to write my code like this, but I seem to be stuck. Is it possible to rewrite the code using Promise.all and await with a dynamic array of requests? Please advise. Below is what I have:
'use strict';
const { apiCreateRecords } = require('../../../records/createRecords');
const createRecords = async (req, headers) => {
let body = [];
let status;
for(let i = 0; i < req.body.length; i++) {
let r = req.body[i];
let record = {
recordId: r.record_Id,
recordStatus: r.record_status,
};
const response = await apiCreateRecords(req, { clientHeaders: headers, record });
status = (status != undefined || status >= 300) ? status : response.status;
body.push(response.body);
};
return { status, body };
};
module.exports = {
createRecords,
};
Okay, I'm going to use fetch API to demonstrate the usage of Promise.all()
Normal usage (for one fetch call)
let user = { username: 'john.doe', password: 'secret' };
try{
let res = await fetch('https://example.com/user/', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(user)
})
console.log('User creation response: ', res);
}
catch(err){
console.error('User creation error: ', err);
}
Now let's use Promise.all()
const users = [
{ username: 'john.doe', password: 'secret' },
{ username: 'jane.doe', password: 'i-love-my-secret' }
];
const requests = [];
// push first request into array
requests.push(
fetch('https://example.com/user/', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(user[0])
})
);
// push second request into array
requests.push(
fetch('https://example.com/user/', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(user[1])
})
);
try{
const responses = await Promise.all(requests);
console.log('User creation responses: ', responses);
}
catch(err){
console.log('User creation error: ', err);
}

Vue - returning the result of a synchronous method

I'm struggling to return the synchronous results of the method below.
I call the method from a different method:
var result = this.getVendor(id)
console.log(result)
Here is the fetch method:
methods: {
async getData(id) {
const response = await fetch(`${API_URL}api/${id}`, {
method: "GET",
headers: {
authorization: `Bearer ${localStorage.token}`
}
})
.then(res => res.json())
.then(data => {
return data;
});
await response;
}
}
How do I return the results response of the getData() function to show in the console?
Async functions Always return a promise.
You can use the await syntax to return it properly.
async getData(id) {
const response = await fetch(`${API_URL}api/${id}`, {
method: "GET",
headers: {
authorization: `Bearer ${localStorage.token}`
}
})
const data = await response.json()
return data
}
You can access the data out of that function anywhere you call it.
let data = null
object.getData(2)
.then(x => {
data = x
})
Also if you are going to use async await make sure to use try and catch to handle any errors that come up.
async getData(id) {
try {
const response = await fetch(`${API_URL}api/${id}`, {
method: "GET",
headers: {
authorization: `Bearer ${localStorage.token}`
}
})
const data = await response.json()
return data
}
} catch(err) {
console.error(err)
}

Categories

Resources