How to provide props.history push as a function's argument - reactjs

I have the following function which I use in two components:
export const removeItem = (id, cb) => {
try {
const remove = async () => {
await axios.delete(`http://localhost:9000/news/${id}`);
cb();
};
remove();
} catch (e) {
console.log(e)
}
}
Im my NewsItemPage component I want to provide props.history.push('/news') as the second argument, but this code would not work:
<button onClick={() => {removeItem(someId, props.history.push('/news')) }}>remove</button>
Any help much appreciated.

You have to put a function around it to be able to use as callback.
like this <button onClick={() => {removeItem(someId, () => {props.history.push('/news')}) }}>remove</button>

Related

pass arrow function to component prop

I am trying to pass the result of the handleRedirectUrl() function to the ShortUrlField component as a prop.
I don't know what I am doing wrong, please help me
const handleRedirectUrl = () => {
urlService
.getShortenedUrl(urls.slice(-1)[0].short_url)
.then((returnedUrl) => {
setRedirectedUrl(returnedUrl);
})
.catch((error) => {
handleCreateErrors(error);
})
.finally(() => {
return redirectedUrl;
});
};
//display shortened url
const shortUrlDisplay = renderShortUrl ? (
<ShortUrlField
originalUrlValue={urls.slice(-1)[0].original_url}
shortUrlValue={urls.slice(-1)[0].short_url}
redirectedUrlValue={handleRedirectUrl()}
/>
) : (
<EmptyField />
);
The urlService function
const getShortenedUrl = (urlToGet) => {
const request = axios.get(redirectShortenedUrl + `${urlToGet}`);
return request.then((response) => response.data);
};
Edit 1:
I was not returning anything with my handleRedirectUrl function. Also, I was not passing it properly to the props. I have changed my code to
const handleRedirectUrl = () => {
return urlService
.getShortenedUrl(urls.slice(-1)[0].short_url)
.then((returnedUrl) => {
setRedirectedUrl(returnedUrl);
})
.catch((error) => {
handleCreateErrors(error);
})
.finally(() => {
return redirectedUrl;
});
};
//display shortened url
const shortUrlDisplay = renderShortUrl ? (
<ShortUrlField
originalUrlValue={urls.slice(-1)[0].original_url}
shortUrlValue={urls.slice(-1)[0].short_url}
redirectedUrlValue={handleRedirectUrl}
/>
) : (
<EmptyField />
);
It does not work. the getShortenedUrl function is never called
Edit 2: Added the ShortUrlField component code
import React from "react";
const ShortUrlField = (props) => {
return (
<div>
<p>
<a href={props.originalUrlValue}>{props.originalUrlValue}</a> became{" "}
<a href={props.redirectUrlValue}>{props.shortUrlValue}</a>
</p>
</div>
);
};
export default ShortUrlField;
Edit 3: I made it work!!
Many thanks to #ZsoltMeszaros for pointing out the right path to me.
I have passed a state variable to my conditional rendered component, and added an effect hook that basically sets the state if the component is rendered.
Much thanks to all of you that commented.
I didn't understand where is this setRedirectURL function, but anyway your handleRedirectUrl function returns nothing
const handleRedirectUrl = () => {
return urlService
.getShortenedUrl(urls.slice(-1)[0].short_url)
.then((returnedUrl) => {
setRedirectedUrl(returnedUrl);
})
.catch((error) => {
handleCreateErrors(error);
})
.finally(() => {
return redirectedUrl;
});
};
May this can work as you can see like your axios request, this is returning result of urlService.

Sending value with fireEvent

I'm using the fireEvent from #testing-library/react.
I declared a react component as follows:
const CustomParamTest = () => {
onButtonClick(customParam) {
console.log(customParam);
}
return (
<>
<button
data-testid="custom-param-button"
onClick={(customParam) => onButtonClick(customParam) }
>
Custom param
</button>
</>
);
}
I have this test:
describe('basic test', () => {
test('items should be empty', () => {
const { getByTestId } = render(<CustomParamTest />);
const customButton = getByTestId('custom-param-button');
fireEvent.click(customButton);
});
});
What I want to achive is to send a custom parameter with the click event, something like this:
fireEvent.click(customButton, myCustomParameter);
I want to access the myCustomParameter inside my onButtonClick function. I could make it work as follow but I want a better solution:
I created a custom click event like this:
const customEvent = createEvent.click(customButton, { button: 2 });
customEvent.myCustomProp = 'customValue';
fireEvent.click(customButton, customEvent);
And in my component I can access this value like this:
onClick={(e) => console.log(e.nativeEvent.myCustomProp)}
I feel like there should be a better way to do this.

How to add two event for the On submit

How to add react typescript forms in the two events for the onSubmit
<Form onSubmit={this.onSaveMybus}> and onSubmit={handleSubmit}
Anyone know how to add this correctly
<Form onSubmit={() => {this.onSaveMybus();this.handleSubmit()}>
you can call this way two function at a time in react
You can't call onSubmit two times, so call other method from first onSubmit method.
const onSaveMybus = () =>
{
// perform some task here
handleSubmit();
}
const handleSubmit = () =>
{
// perform some other task here
}
<Form onSubmit={onSaveMybus}></Form>
const firstFunction = () => {
...doFirstStuff
}
const secondFunction = () => {
...doSecondStuff
}
const onSaveMybus = () => {
firstFunction()
secondFunction()
}
<Form onSubmit={onSaveMybus} />

Can async functions be called in onClick in button react

I am going to call async function in onclick event in button. But it is not working. Is it possible to call the async function inside button onlick ?
Here is the code.
Filter button
const FilterButton = (props) => {
return (
<div className="p-2 ">
<button className="btn btn-secondary" onClick={props.fetchInvoices}>Filter</button>
</div>
);
};
fetchInvoices async function
fetchInvoices = async () => {
const invoices = await getInvoices(this.currentState.params);
this.props.store.dispatch(UpdateInvoices(invoices));
};
code to pass function to component
<SearchField store = {this.props.store} fetchInvoices={this.fetchInvoices}/>
This is how I call my asyncs inside an onClick:
<Button onClick={async () => {await this.asyncFunc("Example");} }/>
async asyncFunc(text) {
console.log(text);
}
Your async function:
const asyncFunc = async () => {
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("I am a done promise!"), 3000)
});
let result = await promise
alert(result);
}
Your button component call:
<button onClick={asyncFunc} >I am a button!</button>
Instead, try doing
<button className="btn btn-secondary" onClick={this.handleFetchInvoices}>Filter</button>
handleFetchInvoices(){
this.props.fetchInvoices
}
<button
onClick={(e) => (async () => {
try {
const invoices = await getInvoices(this.currentState.params);
} catch () {
}
})()}
>I am a button!</button>
In general, it is a bad practice to create an 2x functions inside the button with each click. But it works.

not getting the value from outside render function

i am new to react. please help me.
i am trying the get a value of data outside render.
data.map(
<button onClick = { () => { console.log (data)}}></button>
)
i am getting the value of data here. but
handleClick = () => {
console.log (data) /// not getting the value
}
<button onClick = { this.handleClick}></button>
if i try this.hadleClick , then i am not getting any value. why . thanks,
It's because you are not passing the value to your handleClick function. A couple options:
Bind the function with the params in your onClick:
data.map(
<button onClick = { this.handleClick.bind(this, data) }></button>
)
Pass an anonymous function to your click handler:
data.map(
<button onClick = { () => this.handleClick(data) }></button>
)
And you'll need to update your handleClick function to accept data as a param:
handleClick = data => {
console.log(data);
}
You should be passing the data you want to print to the function like below:
<button onClick = { () => this.handleClick(data) }></button>
(and your handler function should accept it as well)
handleClick = (data) => console.log(data);

Resources