How do I pass an ID from one API to another, and fetch the require data?
This is my code:
handleClick(e){
fetch("http://api.com/product_sub_categories?category_id")
.then(res => res.json())
.then(
(result) => {
this.setState({
isLoaded: true,
product_sub_categories: result.product_sub_categories
});
},
(error) => {
this.setState({
isLoaded: true,
error
});
}
)
}
You can do using back tick.
handleClick(e){
fetch(`${BASE_PATH}/product_sub_categories?category_id=${e.target.value}`)
.then(res => res.json())
.then(
(result) => {
this.setState({
isLoaded: true,
product_sub_categories: result.product_sub_categories
});
},
(error) => {
this.setState({
isLoaded: true,
error
});
}
)
}
Related
There is a list of notifications from the backend. Each notification has a delete button. If I click the delete button of any notification, I want that notification to be deleted.
How do I do this?
my service
const remove = (notificationDto) => {
return new Observable((observer) => { //<NotificationDto>
axiosInstance
.delete(SERVICE_PATH + '/remove', notificationDto)
.then((response) => {
observer.next(response.data);
observer.complete();
})
.catch((err) => {
console.log(err);
});
});
};
html
<div className="notificationlist__container only-desktop">
{props.notification.notificationList.map((notification) => {
return (
<div className="notificationlist__time">
{notification.notificationDay}
<div className="delete__button">
<AS.IconButton onClick={() => notificationDataUpdateDeleteClick(notification)}>
<AS.DeleteIcon />
</AS.IconButton>
</div>
</div>
);
})}
</div>
where i call the service
After sending notification as payload, the problem was solved
import { InAppNotificationsService } from 'services/InAppNotificationsService';
import { NotificationContext } from 'contexts/NotificationContext';
const { notificationData, setNotificationData } = useContext(NotificationContext);
const notificationDataUpdateDeleteClick = (notification) => {
InAppNotificationsService.remove({ data: notification }).subscribe({
next: (response) => {
InAppNotificationsService.allNotifications({ nationalId: tckn, externalContactNumber: contactInfo?.externalContactNumber }).subscribe({
next: (response) => {
setNotificationData(response);
},
error: (error) => {
console.log(error);
}
});
},
error: (error) => {
console.log(error);
}
});
};
// how can I use the promise of toastify like I want to show spinner while fetching data then message success or failed
// but I am getting error in bellow code
const fetch = () => {
axios
.get("https://restcountries.com/v2/name/india")
.then((res) => {
toast.promise({
pending:"pending",
success:"success",
error:"rejected"
} )
console.log(res);
})
.catch((err) => {
toast.error("🦄 failed", {
position: "top-center",
autoClose: 2000,
hideProgressBar: true,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined
});
});
};
According to toast API https://fkhadra.github.io/react-toastify/promise/ the syntax should be
const myPromise = fetchData();
toast.promise(myPromise, {
loading: 'Loading',
success: 'Got the data',
error: 'Error when fetching',
})
An example which can be found on https://codesandbox.io/s/twilight-bash-jzs24y?file=/src/App.js
export default function App() {
const myPromise = new Promise((resolve) =>
fetch("https://jsonplaceholder.typicode.com/todos/1")
.then((response) => response.json())
.then((json) => setTimeout(() => resolve(json), 3000))
// setTimeout just for the example , cause it will load quickly without it .
);
useEffect(() => {
toast.promise(myPromise, {
pending: "Promise is pending",
success: "Promise Loaded",
error: "error"
});
}, []);
return (
<div className="App">
<ToastContainer />
</div>
);
}
If you are not using promise. Use toast.loading.
(DOCS: https://fkhadra.github.io/react-toastify/promise/#toastloading)
const getData = () => {
const id = toast.loading("Please wait...")
axios.get(`some-url`)
.then(res => {
toast.update(id, {render: "All is good", type: "success", isLoading: false});
}).catch(err => {
toast.update(id, {render: "Something went wrong", type: "error", isLoading: false });
});
}
If it is not working then store toast id in useRef and then it will work.
You can use toast.update (https://fkhadra.github.io/react-toastify/update-toast)
const toastId = useRef(null)
const fetch() => {
toastId.current = toast.loading("Loading...")
axios
.post(...)
.then(() => {
toast.update(toastId.current, {
render: "Your message...",
type: "success",
isLoading: "false"
}
})
.catch(() => {
toast.update(toastId.current, {
render: "Your message...",
type: "error",
isLoading: "false"
}
})
}
I'm learning react by building a weather api. I make an API call and store it in state.
state = {
forecasts: {
error: null,
isLoaded: false,
forecasts: []
}
}
componentDidMount() {
const endpoint = `http://dataservice.accuweather.com/forecasts/v1/daily/5day/207931?apikey=KEY&language=en&details=true&metric=true`;
fetch(endpoint)
.then(res => res.json())
.then((result) => {
this.setState({
'forecasts.isLoaded': true,
'forecasts.forecasts': result.DailyForecasts,
});
},
(error) => {
this.setState({
'forecasts.isLoaded': true,
'forecasts.error': error
});
})
}
When I pass this down as props, I get no data?
<WeatherOverview weather={this.state.forecasts}/>
Use spread syntax to copy the entire previous object and then override some of its keys. You should also use the form of setState that takes a function because you want to reference the previous value of state.forecasts:
.then((result) => {
this.setState(state => ({
forecasts: {
...state.forecasts,
isLoaded: true,
forecasts: result.DailyForecasts,
},
}));
},
(error) => {
this.setState(state => ({
forecasts: {
...state.forecasts,
isLoaded: true,
error: error,
},
}));
})
or you may want entirely new objects to wipe out the previous error state:
.then((result) => {
this.setState({
forecasts: {
error: null,
isLoaded: true,
forecasts: result.DailyForecasts,
},
});
},
(error) => {
this.setState(state => ({
forecasts: {
forecasts: [],
isLoaded: true,
error: error,
},
}));
})
you are not passing the state correctly, you need to pass the state without quotation marks
this.setState({
'forecasts.isLoaded': true,
'forecasts.forecasts': result.DailyForecasts,
});
should be like this:
this.setState({
forecasts: {
...state.forecasts,
isLoaded:true,
forecasts:result.DailyForecasts},
});
If Get2 returnsnull, it tries to set the default to Get1 ->selectedTabId: res.data [0] .id, selectedTodoId: res.data [0] .id. If Get2 returns an object with the properties, it wants to set the active tab and the task based on what will returnGet2 `` selectedTabId: res.data.task_id, selectedTodoId: res.data.task_id. Currently, selectedTabId: res.data[0].id, selectedTodoId: res.data[0].id is always set for me. Get2 returns me a specific task (id) that appears in the array withGet1 Please, give me some tips.
Code here: https://stackblitz.com/edit/react-soyase
class App extends React.Component {
constructor() {
super();
this.state = {
selectedTodoId: '',
selectedTabId: null,
items: [],
selectIndex: null
};
}
componentDidMount() {
/*Get1*/
axios({
url: 'https://app',
method: "GET"
})
.then(res => {
this.setState({
items: res.data,
selectedTabId: res.data[0].id,
selectedTodoId: res.data[0].id
});
})
.catch(error => {
console.log(error);
})
/*Get2*/
axios({
url: 'https://app/tasks',
method: "GET"
})
.then(res => {
this.setState({
checkRunning: res.data,
checkRunningId: res.data.id,
selectedTabId: res.data.id
});
})
.catch(error => {
console.log(error);
})
}
select = (id) => {
this.setState({
selectedTodoId: id,
selectedTabId: id
})
}
isActive = (id) => {
return this.state.selectedTabId === id;
}
render() {
return (
<div>
<ul>
{
this.state.items
.map((item, index) =>
<Item
key={index}
index={index}
item={item}
select={this.select}
items = {this.state.items}
selectIndex = {this.state.selectIndex}
isActive= {this.isActive(item.id)}
/>
)
}
</ul>
</div>
);
}
}
You have to chain these promises directly, so that you can make sure, that the default Get1 is set, before you try to set the Get2. Look at this code to see how you could Implement it.
componentDidMount() {
/*Get1*/
axios({
url: 'https://app',
method: "GET"
})
.then(res => {
this.setState({
items: res.data,
selectedTabId: res.data[0].id,
selectedTodoId: res.data[0].id
});
})
.catch(error => {
console.log(error);
})
.then(() => {
/*Get2*/
axios({
url: 'https://app/tasks',
method: "GET"
})
.then(res => {
if (res) {
this.setState({
checkRunning: res.data,
checkRunningId: res.data.id,
selectedTabId: res.data.id
});
}
})
.catch(error => {
console.log(error);
})
});
}
Now you set the default id tab from Get1 and after that, you download Get2 and if Get2 returns a valid object (you could extend that if(res) to check if it is an actual object and a valid response), the downloaded Get2 id is set. Hope this helps.
I have action that always returns Promise.reject:
module.exports = { create: createActionAsync('CREATE_USER', () => {
return Promise.reject({
response: {
type: 'error',
message: 'It will be implemented soon',
},
});
})}
But in component catch block doesn't work:
onAddUser(data) {
const { userActions: { create } = {} } = this.props;
create(data)
.then(() => {})
.catch(err => console.error(err)) // not working