React dropdown fetch from API - reactjs

I want to build "React Dropdown", which will give me options to select user while I type first letters of his name.
Users data is coming from my backend API in JSON format.
// http://localhost:5000/users
{
"users": [
{
"company_id": 1,
"name": "Sally Mae"
},
{
"company_id": 2,
"name": "Johnathan Ives"
},
{
"company_id": 3,
"name": "John Smith"
}
]
}
here's my fetch part, but I can't fetch, but my server is running, this is the code
fetchData = (inputValue, callback) => {
if (!inputValue) {
callback([]);
} else {
setTimeout(() => {
fetch("http://127.0.0.1:5000/users/" + inputValue, {
method: "GET",
})
.then((resp) => {
console.log(resp);
return resp.json()
})
.then((data) => {
const tempArray = [];
data.forEach((users) => {
console.log(tempArray);
tempArray.push({ label: `${users.name}`, value: `${users.name}`});
console.log(tempArray);
});
callback(tempArray);
})
.catch((error) => {
console.log(error, "catch the hoop")
});
});
}
}
appreciate any help !

I think what you misunderstand here is that callback, of your loadOptions prop, is where you wrap your retrieval method.
const getData = (inputValue) =>
fetch('http://127.0.0.1:5000/users/' + inputValue, {
method: 'GET',
})
.then((resp) => resp.json())
.then((data) =>
data.map((user) => ({ label: user.name, value: user.name }))
)
.catch((error) => {
console.log(error, 'catch the hoop');
});
const fetchData = (inputValue, callback) => {
if (!inputValue) {
callback(Promise.resolve([]));
} else {
callback(getData(inputValue));
}
};

Related

How to make api call with optional payload in React JS

I am trying to call API in React JS with AXIOS. I need to send payload as optional when productID has value.
This is my service.js file
fetchProducts: (payload) => put(`/products`, payload),
fetchProductsProductID: (params, payload) => put(`/products`, payload, { params }),
products.js
useEffect(() => {
if (productID) {
CommonSrv.fetchProductsProductID(
{ productID: productID },
{
data: data,
},
)
.then((resp) => {
console.log(resp)
})
.catch((err) => {
console.log(err)
});
} else {
CommonSrv.fetchProducts({ data: data })
.then((resp) => {
console.log(resp)
})
.catch((err) => {
console.log(err)
});
}
}, [])
within the then and catch blocks same conditions I need to use. Because of productID, I am duplicating my code a lot how can I simply this code.
You can try something like that!
(productID ?
CommonSrv.fetchProductsProductID(
{ productID: productID },
{
data: data,
},
)
:
CommonSrv.fetchProducts({ data: data }))
).then(.....).catch(...)

Internal server error 500 react post to firebase

I'm getting a 500 error when posting to my firebase database. However, when I post via postman, it works fine, thus I'm having a lot of trouble debugging this. For the moment, I've hardcoded the categoryId and also the newRow, to make sure there wasn't a problem with my state somehow.
I think the handleSubmit is the only relevant function
handleSubmit = (event) => {
event.preventDefault();
const categoryId = "1RegisterInfo";
const newRow = {
index: "3",
body: "this.state.body",
dataType: "this.state.dataType",
visit: "test",
};
this.props.postRow(categoryId, { newRow });
};
action
export const postRow = (categoryId, rowData) => (dispatch) => {
dispatch({ type: "LOADING_UI" });
axios
.post(`/category/${categoryId}`, rowData)
.then((res) => {
dispatch({
type: "POST_ROW",
payload: res.data,
});
dispatch(clearErrors());
})
.catch((err) => {
dispatch({
type: "SET_ERRORS",
payload: err.response.data,
});
});
};
cloud function
exports.postRow = (req, res) => {
if (req.body.body.trim() === "") {
return res.status(400).json({ comment: "Must not be empty" });
}
if (req.body.index.trim() === "") {
return res.status(400).json({ comment: "Must not be empty" });
}
if (req.body.dataType.trim() === "") {
return res.status(400).json({ comment: "Must not be empty" });
}
if (req.body.visit.trim() === "") {
return res.status(400).json({ comment: "Must not be empty" });
}
const newRow = {
index: req.body.index,
dataType: req.body.dataType,
visit: req.body.visit,
body: req.body.body,
createdAt: new Date().toISOString(),
categoryId: req.params.categoryId,
disapproveCount: 0,
approveCount: 0,
};
db.doc(`/categories/${req.params.categoryId}`)
.get()
.then((doc) => {
if (!doc.exists) {
return res.status(404).json({ error: "Category not found" });
}
})
.then(() => {
return db.collection("rows").add(newRow);
})
.then(() => {
res.json(newRow);
})
.catch((err) => {
console.log(err);
res.status(500).json({ error: "Something went wrong" });
});
};
Any help appreciated!
You're not sending the right payload.
{ newRow }
is the same as
{
newRow: {
index: '3',
body: this.state.body,
dataType: this.state.dataType,
visit: 'test',
},
}
You're passing the above data in the request body and so req.body.body is undefined causing req.body.body.trim() to fail.
this.props.postRow(categoryId, { newRow })
should be
this.props.postRow(categoryId, newRow)
I would recommend using Joi or something similar to validate the request payload before trying to do any other operation.

call function synchronously in reactjs

I want to call function only after previous function gets executed. I tried with promises but its not working,I also tried with async await but the last function is getting executed.After execution of first function its state value i want to pass to next function and so on.Please help me in this.Thanks in advance.
handleAllFunctionsOnClickPayLater() {
let promise = Promise.resolve();
promise
.then(() => this.handleGuestLogin())
.then(() => setTimeout(this.handleAddress(),1000))
.then(() => setTimeout(this.handlePayLater(),2000))
}
handleGuestLogin() {
const UserDetails = {
name: this.state.name,
email: this.state.email,
mobile: this.state.number
}
fetch(api,{
method : 'POST',
body: JSON.stringify(UserDetails)
})
.then(res => res.json())
.then(data => {
return this.setState({
cid: data.Data.cid
},() => {console.log(this.state.cid)})
})
}
handleAddress() {
var address_details = {
cid:this.state.cid
...other details
}
fetch(api,{
method : 'POST',
body: JSON.stringify(address_details)
})
.then(res => res.json())
.then(data => {
console.log("address added in db customer_address",data);
return this.setState({
address_id: data.address_id,
})
}
handlePayLater = () => {
var bookingDetails = {
cid: this.state.cid,
address_id: this.state.address_id
}
fetch(api,{
method : 'POST',
body : JSON.stringify(bookingDetails)
})
.then(res => res.json())
.then(data => {
return this.setState({bookingId:data.booking_id});
}
Assuming handleAddress, handleGuestLogin and handlePayLater return promises, you can use an async/await function
synchronousPromises = async () => {
try {
const handleGuestLoginResult = await this.handleGuestLogin();
const handleAddressResult = await this.handleAddress();
const handlePayLaterResult = await this.handlePayLater();
} catch (error)
{
return reject(error); //will cause .catch to fire
}
return resolve([
handleGuestLoginResult,
handleAddressResult,
handlePayLaterResult
]); //will cause .then to fire
}
since synchronousPromises is an async function, it itself returns a promise. to use it, you can call it as
callSyncronousPromises = () => {
synchronousPromises()
.then(success => {
//handle success
})
.catch(error => {
//handle error
}
}

Jest React Redux Testing

I am new to redux and I want to know how to test Actions and Reducers.
I have attached a copy of both the files and would like anyone to help with a common pattern which I can use.
I am using Jest for unit testing.
URL is http://localhost:30001.
Just want to know how the testing can be done and how I can use fetch in my test cases and what can I put as my expected result.
Actions page
import {
REQUEST_CHARITIES,
REQUEST_PAYMENT,
SHOW_DONATION_AMOUNT_LIST,
UPDATE_DONATION_AMOUNT_LIST,
URL,
PAY_NOW,
UPDATE_MESSAGE,
UPDATE_TOTAL_DONATE
} from './const';
//get list of all the charities
export function requestCharitiesList() {
const request = fetch(`${URL}/charities`, {
method: 'GET'
}).then(response => response.json())
return {
type: REQUEST_CHARITIES,
payload: request
}
}
//get list of all payment amount
export function requestDonationAmount() {
return {
type: REQUEST_PAYMENT,
payload: [{
"id": 0,
"price": 10
},
{
"id": 1,
"price": 20
},
{
"id": 2,
"price": 50
},
{
"id": 3,
"price": 100
},
{
"id": 4,
"price": 500
},
]
}
}
//get the total count of charities and update the payment options list visibility
export function showDonationList() {
const paymentOptionsShow = []
const request = fetch(`${URL}/charities`, {
method: 'GET'
}).then( response => response.json())
request.then(function(result) {
if(result.length >= 1){
let arrayLength = result.length
for( var i = 0 ; i < arrayLength ; i++ ) {
paymentOptionsShow.push({active: false });
}
}
})
return {
type: SHOW_DONATION_AMOUNT_LIST,
payload: paymentOptionsShow
}
}
//to show and hide the payment options for each card
export function updateDonationList(list,id){
return {
type: UPDATE_DONATION_AMOUNT_LIST,
payload: {
"list": list,
"id": id
}
}
}
//post the current paid amount
export function payNow(id, amount, currency) {
const request = fetch(`${URL}/payments`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: `{ "charitiesId": ${id}, "amount": ${amount}, "currency": "${currency}" }`
})
.then(response => response.json())
return {
type: PAY_NOW,
payload: request
}
}
//show thank you message
export function updateMessage(message) {
return {
type: UPDATE_MESSAGE,
message: message
}
}
//get the total number of payments made
export function summaryTotal() {
const request = fetch(`${URL}/payments`,
{ method: 'GET' }).then(response => response.json())
return {
type: UPDATE_TOTAL_DONATE,
payload: request
}
}
One of my Reducers
import {
REQUEST_CHARITIES
} from '../actions/const'
export default function (state = null, action) {
switch (action.type) {
case REQUEST_CHARITIES:
return action.payload
default:
return state;
}
}
So, this is a simple example of how my comment could work. Understand?
describe('Test case', () => {
it('should return a new state', () => {
const myReducer = nameOfReducer( { state }, { action } );
expect(myReducer).toEqual({ state });
});
});

Fetch and store data from multiple url for the sections data of SectionList

I would like to use the SectionList in react native.
export default class Home extends React.Component {
constructor(props) {
super(props);
this.state = {
dataSource: [
{
title: 'New List', data: []
},
{
title: 'Old list', data: []
},
]
}
}
render() {
return (
<SectionList
style={styles.SectionContainer}
sections={this.state.dataSource}
renderSectionHeader={this._renderSectionHeader}
renderItem={this._renderItem}
keyExtractor={(item) => item.id}
/>
)
}
}
Each section's data can be fetched by separate url, and they basically have the same json data:
getNewList() {
const url = website + '/api/new-list/';
return fetch(url)
.then((res) => res.json())
.catch((err) => console.log(err))
},
getOldList() {
const url = website + '/api/old-list/';
return fetch(url)
.then((res) => res.json())
.catch((err) => console.log(err))
}
How can fetch and store both the response data for the dataSource of SectionList?
Sounds like you need to fire off multiple promises and wait for all to complete. Axios has an awesome .all helper utility that lets you pass in an array of promises and then waits for all of them to finish before running resolving:
function getUserAccount() {
return axios.get('/user/12345');
}
function getUserPermissions() {
return axios.get('/user/12345/permissions');
}
axios.all([getUserAccount(), getUserPermissions()])
.then(axios.spread(function (acct, perms) {
// Both requests are now complete
}));
You can also do something close to this using native Promises:
getLists(){
this.getListData().then( responses => {
this.setState({
dataSource: [
{
title: 'New List', data: responses[0]
},
{
title: 'Old list', data: responses[1]
},
]
)};
});
}
getListData(){
return new Promise( (resolve, reject) => {
let completes = 0;
let responses = [];
let url = website + '/api/new-list/';
fetch(url)
.then((res) => {
responses.push(res.json());
completes++;
if(completes === 2){
resolve(responses);
}
})
.catch((err) => console.log(err));
url = website + '/api/old-list/';
fetch(url)
.then((res) => {
responses.push(res.json());
completes++;
if(completes === 2){
resolve(responses);
}
})
.catch((err) => console.log(err))
});
}

Resources