here I have a problem when creating a search bar in reactjs.
// So, I have an endpoint like this
export const getCountPoiCategoryProvinsi = (provinsi) => {
return new Promise((resolve, reject) => {
axios
.get(
`${baseUrl}/api/dashboard/v1/getCountPoiCategoryProvinsi?provinsi=${provinsi}`,
{
headers: { Authorization: `Bearer ${token}` },
}
)
.then((response) => {
resolve(response.data.data);
})
.catch((error) => {
if (error.response?.data.code === 404)
resolve({ lists: [], totalCount: 0 });
console.log(error.response);
reject(error?.response?.data?.message || "Network error.");
});
});
};
// The code for the fetch is like this
const loadPosts = async (provinsi) => {
try {
setLoading(true);
const result = await getCountPoiCategoryProvinsi(provinsi);
setPosts(result);
console.log(result);
} catch (error) {
console.log("salah");
} finally {
setLoading(false);
}
};
loadPosts();
// and the code in the return section is like this
{loading ? (
<h4>Loading ...</h4>
) : (
posts
// eslint-disable-next-line array-callback-return
.filter((value) => {
if (searchTitle === "") {
return value;
} else if (
value.title.toLowerCase().includes(searchTitle.toLowerCase())
) {
return value;
}
})
.map((item, index) => (
<h5 key={index}>
{item.category} + {item.jumlah_category}
</h5>
))
)}
When I try in the browser and type in the search bar the data doesn't appear.
the console doesn't appear either.
what do you think is wrong in my code? Thank You
According to your fetch code, your loadPosts function did not have any input when called so likely your getCountPoiCategoryProvinsi function return an empty array.
Related
nestjs controller.ts
#Patch(':id')
async updateProduct(
#Param('id') addrId: string,
#Body('billingAddr') addrBilling: boolean,
#Body('shippingAddr') addrShipping: boolean,
) {
await this.addrService.updateProduct(addrId, addrBilling, addrShipping);
return null;
}
nestjs service.ts
async updateProduct(
addressId: string,
addrBilling: boolean,
addrShipping: boolean,
) {
const updatedProduct = await this.findAddress(addressId);
if (addrBilling) {
updatedProduct.billingAddr = addrBilling;
}
if (addrShipping) {
updatedProduct.shippingAddr = addrShipping;
}
updatedProduct.save();
}
there is no problem here. I can patch in localhost:8000/address/addressid in postman and change billingAddr to true or false.the backend is working properly.
how can i call react with axios?
page.js
const ChangeBillingAddress = async (param,param2) => {
try {
await authService.setBilling(param,param2).then(
() => {
window.location.reload();
},
(error) => {
console.log(error);
}
);
}
catch (err) {
console.log(err);
}
}
return....
<Button size='sm' variant={data.billingAddr === true ? ("outline-secondary") : ("info")} onClick={() => ChangeBillingAddress (data._id,data.billingAddr)}>
auth.service.js
const setBilling = async (param,param2) => {
let adressid = `${param}`;
const url = `http://localhost:8001/address/`+ adressid ;
return axios.patch(url,param, param2).then((response) => {
if (response.data.token) {
localStorage.setItem("user", JSON.stringify(response.data));
}
return response.data;
})
}
I have to make sure the parameters are the billlingddress field and change it to true.
I can't make any changes when react button click
Since patch method is working fine in postman, and server is also working fine, here's a tip for frontend debugging
Hard code url id and replace param with hard coded values too:
const setBilling = async (param,param2) => {
// let adressid = `${param}`;
const url = `http://localhost:8001/address/123`; // hard code a addressid
return axios.patch(url,param, param2).then((response) => { // hard code params too
console.log(response); // see console result
if (response.data.token) {
// localStorage.setItem("user", JSON.stringify(response.data));
}
// return response.data;
})
}
now it worked correctly
#Patch('/:id')
async updateProduct(
#Param('id') addrId: string,
#Body('billingAddr') addrBilling: boolean,
) {
await this.addrService.updateProduct(addrId, addrBilling);
return null;
}
const ChangeBillingAddress = async (param) => {
try {
await authService.setBilling(param,true).then(
() => {
window.location.reload();
},
(error) => {
console.log(error);
}
);
}
catch (err) {
console.log(err);
}
}
const setBilling= async (param,param2) => {
let id = `${param}`;
const url = `http://localhost:8001/address/`+ id;
return axios.patch(url,{billingAddr: param2}).then((response) => {
if (response.data.token) {
localStorage.setItem("user", JSON.stringify(response.data));
}
return response.data;
})
}
I'm checking if the env is development or prod, If development I'm returning mock data else I'm making an API call to fetch data.
Now I'm getting this ES lint Error,
Expected to return a value at the end of arrow function.
What I'm doing wrong here ? please help
export const getData = (request: any) => {
if (process.env.NODE_ENV !== 'development') {
axios.post(EMAIL_DISPUTE_API, { request })
.then((res) => {
return res.data;
})
.catch((e) => {
console.log(e);
});
} else {
return emailDisputeMockResponse;
}
};
Requires return statements to either always or never specify values.
Try without else bloc
export const getData = (request: any) => {
if (process.env.NODE_ENV !== 'development') {
axios.post(EMAIL_DISPUTE_API, { request })
.then((res) => {
return res.data;
})
.catch((e) => {
console.log(e);
});
}
return emailDisputeMockResponse;
};
in case of your function,if block don't return value but else return emailDisputeMockResponse, so you need declare return value type for your function and return value in the catch block, just like following code snippet
export const getData = async (request: any): Promise<emailDisputeResponse | null> => {
let result: emailDisputeResponse | null
if (process.env.NODE_ENV !== 'development') {
result = await axios.post(EMAIL_DISPUTE_API, { request })
.then((res) => {
return res.data;
})
.catch((e) => {
console.log(e);
return null;
});
} else {
result = emailDisputeMockResponse;
}
return result
};
I am trying to use Express + MongoDB building React app.
I was able to post some documents to MongoDB. Currently, I'm trying to figure out how to print fetched data to the screen.
I have these routes:
router.post('/totalbalance', (request, response) => {
const totalBalance = new TotalBalanceModelTemplate({
totalBalance:request.body.totalBalance,
});
totalBalance.save()
.then(data => {
response.json(data);
})
.catch(error => {
response.json(error);
});
});
router.get('/totalbalance', (request, response) => {
TotalBalanceModelTemplate.find(request.body.totalBalance, (error, data) => {
if (error) {
return error
} else {
response.json(data[0])
}
})
});
This is axios request:
useEffect(() => {
const resp = axios.get('http://localhost:4000/app/totalbalance');
console.log(resp);
}, []);
It returns a promise that has a parameter data which equals to object value which is the first value in the array
data: {_
id: "60c48b4ec60919553d92319f",
totalBalance: 5555,
__v: 0
}
and prints it out to the console.
How can I print out to the console the value totalBalance instead of whole promise?
By the way, sometime the array of data is empty (there are no documents in the DB), how should i handle these cases as well?
Thanks!
First of all, Axios GET method does not have any request body. But you are trying to use it in the MongoDB query. - "TotalBalanceModelTemplate.find(request.body.totalBalance, (error, data) => {".
The find query should be object {}. If require pass on conditions to it.
First point, to print only "totalBalance" output. Use, console.log(resp.totalBalance);
Second point, to handle records length, have a if else condition,
if (error) {
return error
} else if (data.length) {
return response.send("No records found")
} else {
response.json(data[0])
}
Try this :
Routes
router.post("/totalbalance", async (req, res) => {
try {
const totalBalance = new TotalBalanceModelTemplate({
totalBalance: req.body.totalBalance,
})
await totalBalance.save();
res.json(totalBalance)
} catch (error) {
res.status(400).json({
message: error.message
})
}
})
router.get("/totalbalance", async (req, res) => {
try {
const totalBalances = await TotalBalanceModelTemplate.find();
res.json(totalBalances)
} catch (error) {
res.status(400).json({
message: error.message
})
}
})
App.js
import React, { useState, useEffect } from 'react';
import axios from 'axios';
export default function App() {
const [data, setData] = useState([]);
const getData = async () => {
try {
const response = await axios.get('http://localhost:4000/app/totalbalance');
await setData(response);
} catch (error) {
console.log(error);
}
};
useEffect(() => {
getData();
}, []);
return (
<div>
{data <= 0 ? (
<div className="empty">
<p>No data!</p>
</div>
) : (
data.map((d) => (
<ul key={d.id}>
<li>{d.totalBalance}</li>
</ul>
))
)}
</div>
);
}
I have a problem in my axios api calls, i'm using 2 apis in the same function, both of axios calls works good alone but when i combine them i got error in the Country components which i will be posting after, the error is ( map is not a function )
const onSerializeData = () => {
const serializedCountries = serializeCountries(selectedCountries, false);
//Print the Countries
console.log(
`Selected Countries: \n ${JSON.stringify(serializedCountries)}`
);
axios
.get(
`https://restcountries.eu/rest/v2/alpha/${
serializedCountries[serializedCountries.length - 1]
}`
)
.then((responose) => {
const CouAllData = responose.data;
console.log("CouAllData", CouAllData);
setCountryAllData([...CountryAllData, CouAllData]);
})
.catch((error) => {
console.log("Error", error);
});
axios
.get(
`https://corona-api.com/countries/${
serializedCountries[serializedCountries.length - 1]
}`
)
.then((responose) => {
const CouData = responose.data.data; //The Data
setCountryData([...CountryData, CouData]); //set The Data to the OBJ
console.log(" setCountryData", CountryData);
})
.catch((error) => {
console.log("Error", error);
});
};
return (
<div>
<Country countries={CountryData} />
<Country countriesAll={CountryAllData} /></div>
}
Country Component
const DataGroup = this.props.countries.map((county) => {
return <Data info={county} />;
});
const DataGroupAll = this.props.countriesAll.map((country) => {
return <Data infos={country} />;
});
return (
<div>
{DataGroup}
{DataGroupAll}
</div>
Data Component
<h1>Name : {this.props.info.code}</h1>
<h1>Date : {this.props.info.updated_at}</h1>
<h1>Name : {this.props.infos.name}</h1>
<h1>Capital : {this.props.infos.capital}</h1>
Try using axios.all() to perform concurrent requests.
function getCountries() {
return axios.get(
`https://restcountries.eu/rest/v2/alpha/${
serializedCountries[serializedCountries.length - 1]
}`
)
}
function getCountries2() {
return axios.get(
`https://corona-api.com/countries/${
serializedCountries[serializedCountries.length - 1]
}`
)
}
Promise.all([getCountries(), getCountries2()])
.then(function (results) {
const countries = results[0];
const countries2 = results[1];
});
I'm new and just started to learn react. I encountered the problem that when I add an element, I do not overload the entire list. Although the update and deletion work fine, and the changes are immediately overwritten. A new item appears in the list after the page is reloaded.
it turns out, I get a list when I mount the component and I pull it out, and when I add a new element, the state is not aware of its change. Probably you need to immediately transfer to the state what came to me with fetchNotes (). How to create it correctly, please tell me, I have already tried to play with willMount () and do all sorts of manipulations, but either I manage to fill in the state, but then I don’t work this.state.map () or any other nonsense ...
My method for adding item:
class Note extends Component {
state = {
text: "",
updateNoteId: null,
};
componentDidMount() {
this.props.fetchNotes();
};
resetForm = () => {
this.setState({text: "", updateNoteId: null});
};
selectForEdit = (id) => {
let note = this.props.notes[id];
this.setState({text: note.text, updateNoteId: id});
};
submitNote = (e) => {
e.preventDefault();
if (this.state.updateNoteId === null) {
this.props.addNote(this.state.text).then(this.resetForm);
} else {
this.props.updateNote(this.state.updateNoteId,
this.state.text).then(this.resetForm);
}
this.resetForm();
};
render() {
return (
<div>
<div style={{textAlign: "right"}}>
{this.props.user.username} (<a onClick={this.props.logout}>logout</a>)
</div>
<h3>Add new note</h3>
<form onSubmit={this.submitNote}>
<input
value={this.state.text}
placeholder="Enter note here..."
onChange={(e) => this.setState({text: e.target.value})}
required />
<input type="submit" value="Save Note" />
</form>
<button onClick={this.resetForm}>Reset</button>
<h3>Notes</h3>
<table>
<tbody>
{this.props.notes.map((note, id) => (
<tr key={`note_${id}`}>
<td>{note.text}</td>
<td><button onClick={() => this.selectForEdit(id)}>edit</button></td>
<td><button onClick={() => this.props.deleteNote(id)}>delete</button></td>
</tr>
))}
</tbody>
</table>
</div>
)
}
}
const mapStateToProps = state => {
return {
notes: state.notes,
user: state.auth.user,
}
};
const mapDispatchToProps = dispatch => {
return {
fetchNotes: () => {
dispatch(notes.fetchNotes());
},
addNote: (text) => {
return dispatch(notes.addNote(text));
},
updateNote: (id, text) => {
return dispatch(notes.updateNote(id, text));
},
deleteNote: (id) => {
dispatch(notes.deleteNote(id));
},
logout: () => dispatch(auth.logout()),
}
};
export default connect(mapStateToProps, mapDispatchToProps)(Note);
reducers/
const initialState = [];
export default function notes(state=initialState, action) {
let noteList = state.slice();
switch (action.type) {
case 'FETCH_NOTES':
return [...state, ...action.notes];
case 'ADD_NOTE':
return [...state, ...action.note];
case 'UPDATE_NOTE':
let noteToUpdate = noteList[action.index];
noteToUpdate.text = action.note.text;
noteList.splice(action.index, 1, noteToUpdate);
return noteList;
case 'DELETE_NOTE':
noteList.splice(action.index, 1);
return noteList;
default:
return state;
}
}
action
export const fetchNotes = () => {
return (dispatch, getState) => {
let headers = {"Content-Type": "application/json"};
let {token} = getState().auth;
if (token) {
headers["Authorization"] = `Token ${token}`;
}
return fetch("/api/notes/", {headers, })
.then(res => {
if (res.status < 500) {
return res.json().then(data => {
return {status: res.status, data};
})
} else {
console.log("Server Error!");
throw res;
}
})
.then(res => {
if (res.status === 200) {
return dispatch({type: 'FETCH_NOTES', notes: res.data});
} else if (res.status === 401 || res.status === 403) {
dispatch({type: "AUTHENTICATION_ERROR", data: res.data});
throw res.data;
}
})
}
};
export const addNote = text => {
return (dispatch, getState) => {
let headers = {"Content-Type": "application/json"};
let {token} = getState().auth;
if (token) {
headers["Authorization"] = `Token ${token}`;
}
let body = JSON.stringify({text, });
return fetch("/api/notes/", {headers, method: "POST", body})
.then(res => {
if (res.status < 500) {
return res.json().then(data => {
return {status: res.status, data};
})
} else {
console.log("Server Error!");
throw res;
}
})
.then(res => {
if (res.status === 201) {
return dispatch({type: 'ADD_NOTE', note: res.data});
} else if (res.status === 401 || res.status === 403) {
dispatch({type: "AUTHENTICATION_ERROR", data: res.data});
throw res.data;
}
})
}
};
I think that I should somehow call setState in order to explicitly indicate the changes, or maybe I need to re-create the request for the backend as when initializing the component?
I will be glad to any hints and help from your side. Thank you in advance!
you should change reducer ADD case as follow :
case 'ADD_NOTE':
return {
...state,
noteList:[action.note,...state.noteList]
}