React, The function does not load data - reactjs

How to rewrite the function so that it is updated and loaded every time you change pages. The fact is that the loading function works only on one page, but it does not pass to others, how to change it?
function loadModel(model) {
return function(dispatch) {
dispatch(moveToPending(model))
const resource = require(`../resources/${model}`)
const resourceActions = bindActionCreators(resource.actions, dispatch)
const toaster = new Toaster(dispatch)
return new Promise((resolve, reject) => {
resourceActions[getFunctionName(model)]()
.then(res => {
resolve(model)
dispatch(resolveSubscriptions(model))
})
.catch(err => {
if (debug) console.error(err)
reject({ ...err, model })
dispatch(resolveSubscriptions(model))
toaster.error(`Could not load ${model}!`)
})
})
}
}
Update.
Here's the componentWillMount(), I already have it, what do I need to add to it?
componentWillMount() {
this.props.actions.subscribe(this.subscriptions)
.then(() => {
this.props.actions.fetchRegisters({year: this.state.currentYear, month: defaultMonths()})
.then(() => {
if (!this.props.registers.length) {
this.toaster.warning('There is no data for charts')
}
this.createReportState()
})
})
}

React has some lifecycle methods. You can use componentWillMount or componentDidMount for this purpose. You can pass this function as a prop to other pages and there you can call it in componentWillMount, something like:
componentWillMount() {
this.props.loadModel(//arg);
}
For reference: Component life-cycle methods

Related

How to call a variable inside a then method?

I'm getting client data from the backend and I'am using Axios to call that method.
In then() when I get the response data, I want to make a condition that if its completed, to push it to the new array
export default function Client({selectedClient, setSelectedClient})
console.log(selectedClient) //the value comes
useEffect(() => {
axios
.get('api')
.then((response) => {
const { data } = response; //array of data
console.log(selectedClient) // the value doesn't come
data.forEach(element => {
if (element.CLIENT_ID == selectedClient){
console.log('single element', element)
}
});
})
.catch((error) => console.log("Get Method Error", error.message));
}, []);
So when I put selectedClient inside the then(), it will be empty.
How can I solve this?
You need to have selectedClient as a dependency in useEffect hook. So that hook can updated prop value when component mounts.
export default function Client({selectedClient, setSelectedClient})
console.log(selectedClient) //the value comes
useEffect(() => {
if (selectedClient) {
axios
.get('api')
.then((response) => {
const { data } = response; //array of data
console.log(selectedClient) // the value will come now.
data.forEach(element => {
if (element.CLIENT_ID == selectedClient){
console.log('single element', element)
}
}});
})
.catch((error) => console.log("Get Method Error", error.message));
}, [selectedClient]);
Note - You can remove the added if (selectedClient) { if you wanted to invoke the call even when it's not populated.

How to set state of other component inside an axios get method in react?

I'm using class-based components in react. I have few components named as follows: Blogs, BlogsClient, BlogCard. When Blogs mounts I make a call to a function inside BlogClient named as getBlogContent to fetch me data using axios.
setBlogs = (blogs) => {
this.setState({ "blogs": blogs });
}
componentDidMount() {
getBlogContent(this.setBlogs);
}
where getBlogContent is:
let getBlogContent = (setBlogs) => {
store.set('loaded', false);
axios.get(ADMIN_URL + '/getAllBlogs')
.then(response => {
store.set('loaded', true);
setBlogs(response.data.Response);
})
.catch(error => {
store.set('loaded', true);
store.set('errorMessage', error);
})
}
I'm able to fetch data and update my state properly. But If there comes any error inside Blogs or BlogCard(which is called inside Blogs) it goes inside the catch of getBlogContent whereas it should be only responsible for catching Axios error. What am I missing here?
Ok, so it's hard to tell without knowing these errors..
But nonetheless, you should avoid setting the component's state outside that component. So, your code'd become:
componentDidMount() {
const blogContent = getBlogContent();
if (blogContent !== 'error'j this.setBlogs(blogContent);
}
let getBlogContent = () => {
store.set('loaded', false);
return axios.get(ADMIN_URL + '/getAllBlogs')
.then(response => {
store.set('loaded', true);
return response.data.Response;
})
.catch(error => {
store.set('loaded', true);
store.set('errorMessage', error);
return 'error';
})
}

Pagination in React-Redux

So I'm just trying to make a pagination component in react. Im currently using redux for my state management and using semantic-ui for the pagination component.
I have currently made a react component in my action.jsx file and have two other functions which one of them is for data fetching for my redux state and one other for the declaring the current active page value and set the new target url for data fetching.
export class Paginator extends React.Component {
state = {
page: [],
pages: []
}
handlePage(activePage) {
let pagenum = activePage;
let pagestring = pagenum.toString();
paginationUrl = '/api/v1/products/index/?page=' + pagestring; ----> Pass This Url
}
componentDidMount() {
axios.get("/api/v1/products/index", { withCredentials: true })
.then(response => {
this.setState({
page: response.data.page,
pages: response.data.pages
})
})
.catch(error => {
console.log("Check Login Error", error);
});
}
render() {
return(
<Pagination onPageChange={this.handlePage} size='mini' siblingRange="6"
defaultActivePage={this.state.page}
totalPages={this.state.pages}
/>
)
}
}
export function fetchProducts() {
return (dispatch) => {
dispatch(fetchProductsRequest())
axios
.get("To Here !")
.then(response => {
// response.data is the products
const products = response.data.products
dispatch(fetchProductsSuccess(products))
})
.catch(error => {
// error.message is the error message
dispatch(fetchProductsFailure(error.message))
})
}
}
The question is how am i able to pass the paginationUrl to the function below ? (Actually, there is no way i guess !).
Note: I am only able to use handlePage in the same component with the pagination component.
Waiting for suggestions, Thx in advance ;)
You could pass the URL to the fetchProducts function when dispatching actions on page changes.
handlePage(activePage) {
const url = `/api/v1/products/index/?page=${activePage}`
dispatch(fetchProducts(url))
}
And update the fetchProducts action creator to use the URL.
export function fetchProducts(url) {
return (dispatch) => {
dispatch(fetchProductsRequest())
axios
.get(url)
.then((response) => {
dispatch(fetchProductsSuccess(response.data.products))
})
.catch((error) => {
dispatch(fetchProductsFailure(error.message))
})
}
}
This is unrelated to the question but I would strongly recommend using React Query to simplify data fetching and synchronization.

React and promise issues with fetch method

i'm new in react and i've got some issues with asynchronous fetch data :
i want to fetch github users
function fetchUser(username) {
return fetch(`https://api.github.com/users/${username}`)
.then(response => response.json())
.then(data => data)
}
export function getUserData(username) {
const object = {
profile: fetchUser(username),
}
console.log(object)
return object
}
and this is my method in my component
componentDidMount() {
getUserData(this.props.playerOne)
}
but this is what i got in my console
{profile: Promise}
i'm sure that i dont understand well this promise so could you help me to have not a Promise in my object but the data i'm fetching ? (if i log data in my fetch i got what i want)
You can make this function async and wait for the promise resolution.
export async function getUserData(username) {
const object = {
profile: await fetchUser(username),
}
console.log(object)
return object
}
then in your componentDidMount
componentDidMount() {
getUserData(this.props.playerOne)
.then((profile) => { this.setState({ profile }) })
}

Jest/Enzyme/Reactjs testing function used by react component

Hi I have this function (apiCall) that calls an API inside a component and uses the data to update state (to then render a chart with chartjs). I want to test specifically the process inside componentDidMount that updates state without calling the API. After lots of time spent searching for a way of mocking this I still haven't been able to figure it out. Trying to assert the changed state from a mock apiCall function.
this is the apiCall function:
const apiCall = (uri) => {
return fetch(uri)
.then( (res) => {
return res
})
.catch( (ex) => {
return 0
})
}
export default apiCall;
// and this is the componentDidMount
componentDidMount() {
apiCall(this.props.uri)
.then((result) => result.json())
.then((result) => {
this.setState({ data: result });
})
this.setState({ legend: this.props.legend })
}
One of the options is to use fetch-mock
http://www.wheresrhys.co.uk/fetch-mock/
Use proxyquire and mock promise function

Resources