First, I POST the parent object and its ID comes back from the server. I need to then include that ID while POSTing the another post call .i am having difficulty in chaining the multiple api call.i having difficulty managing then and catch in react axios post?
code*
parent
var hold
axios.post(/,data)
.then((res) => {
hold=res.data.msg
.then(axios.post(/${hold},data1))
.catch((err) => {
toast.error("Error aayo add vayena");
});
})
.catch((err) => {
toast.error("Error cannot post");
});
You should consider using async/await syntax for handling chained promises, since it helps for handling them in a easier way, according to this article. However, you have to use this in an async function.
In your case, it could be something like this:
const fetchData = async () => {
try{
await axios.post(/,data).then(res => hold = res.data.msg)
}catch(err) {
console.log("Error cannot post");
}
try{
await axios.post(/${hold},data1)
}catch(err) {
console.log("Error aayo add vayena");
}
}
This way, the second post will be done once the first one is finished
Related
I want to create a ticket functionality. On the main page (the parent) I have a axios get function that once the page is loaded, the useEffect is listing all the tickets components.
On the second page I have the child component where I imported with props the reloadTickets={fetchTickets} method to be used every time I have added a new ticket.
The problem is that If I add a post, one time the post is not added, second time the post is added twice and third time the post is adding too many times on a single form submission. Sometime the post is not added at all, but after I try more times, the post is added twice and more.....
This is my PARENT COMPOENTN
This is my Child component
PS. Sorry for the pictures. But react code cannot be formated to look good on my page.
Well the problem is you are not waiting for axios call to finish, since axios.post method is asynchronous.
You need to make your function async and await axios.post method, here is an example how you can do this.
const createTicket = async (e) => {
e.preventDefault();
try {
await axios.post(postTicketURL, {
userID: userID,
content: ticketArea
}, configHeader);
await reloadTickets();
}
catch (error) {
console.log(error);
}
}
Update: I see that you are already using .then and .catch approach in your parent component, so you can solve this with that like this:
const createTicket = async (e: any) => {
e.preventDefault();
axios.post(postTicketURL, {
userID: userID,
content: ticketArea
}, configHeader).then((res: any) => {
console.log(res);
reloadTickets();
}).catch((err: any) => {
console.log(err);
});
}
But I would recommend async await approach, and also you should refactor your code inside TicketsComponent -> fetchTickets to match that.
Why?
Because async await is much more clear and modern approach and you are avoiding potential callback hell, for example if you now want to wait reloadTickets function to end properly. You can find out more about this topics here:
https://www.loginradius.com/blog/async/callback-vs-promises-vs-async-await/
I'm consuming a web api from my React Native Android project. After updating my react-native version to 0.60.3 my response data is not returning JSON, it returns Blob data structure.
This is what I get from then(res=>{...})
Please look at the image
Screen-Shot-2019-07-18-at-17-25-10.png
The _bodyInit object was returning JSON. But now it returns Blob that I can not reach from Js code.
I tried using functions res.json(), res.text()
They worked! But this time I just got data inside the _bodyInit. I can not reach other parameters like ok, header etc.
This is what I've tried. Like I said, it works. But it returns response with just my data, not other parameters like ok, headers etc.
.then((res) => res.json())
.then((res) => {
if (res.ok) {
// No 'ok' element anymore after .json()
}
});
In the 'devtools' if I click the '_bodyInit' object. Simulator gives error below.
Screen-Shot-2019-07-18-at-17-32-49.png
Do you have any idea to solve this issue?
Thanks in advance!
ok property is with response before you call json method on it. If your response contains json, call json to serialize body as json, if response contains blob, call .blob to serialize body as blob. See more proerties of Response here.
.then((res) => {
console.log("response.ok", res.ok)
// print headers,
console.log("headers", res.headers.forEach(item=>console.log(item)))
// if response if json, call res.json
return res.json()
})
.then((res) => {
// here you will only get json data, not other properties.
console.log("json data is ", res)
});
SOLVED
I found two way to solve this problem.
Using .then() after using .json()
.then((res) => {
if (res.ok) {
res.json().then(res=>{
console.log(res)
})
} else console.log("not ok")
});
Using async and await
.then(async res => {
if(res.ok) {
const response = await res.json()
console.log(response)
} else console.log("not ok")
})
That would be great to see other solutions from you. Thanks.
I wanna use an bot to react to every single message in an channel using discord.js f.e. i got an emoji contest channel and i wanna ad an ✅ and an ✖ reaction on every post in there
ofc, all the unnecesary messages are cleaned up so that there are like 50 messages
Fetch the messages already sent in a channel with TextChannel.fetchMessages().
Iterate through the Collection.
Add reactions with Message.react().
When a new message is sent in the channel, you should also add the reactions.
const emojiChannelID = 'ChannelIDHere';
client.on('ready', async () => {
try {
const channel = client.channels.get(emojiChannelID);
if (!channel) return console.error('Invalid ID or missing channel.');
const messages = await channel.fetchMessages({ limit: 100 });
for (const [id, message] of messages) {
await message.react('✅');
await message.react('✖');
}
} catch(err) {
console.error(err);
}
});
client.on('message', async message => {
if (message.channel.id === emojiChannelID) {
try {
await message.react('✅');
await message.react('✖');
} catch(err) {
console.error(err);
}
}
});
In this code, you'll notice I'm using a for...of loop rather than Map.forEach(). The reasoning behind this is that the latter will simply call the methods and move on. This would cause any rejected promises not to be caught. I've also used async/await style rather than then() chains which could easily get messy.
According to https://discord.js.org/#/docs/main/stable/class/TextChannel
you can use fetchMessages
to get all messages from a specific channel, which then returns a collection of Message
Then you can use .react function to apply your reactions to this collection of message by iterating over it and calling .react on each.
Edit:
channelToFetch.fetchMessages()
.then(messages => {
messages.tap(message => {
message.react(`CHARACTER CODE OR EMOJI CODE`).then(() => {
// Do what ever or use async/await syntax if you don't care
about Promise handling
})
})
})
Im using React with axios to read some data from my backend.
I have a BetBuilder js using axios to read like this:
componentDidMount() {
axios.get('http://localhost:8080/api/matches/')
.then(response => {
console.log("Dentro do didmount");
this.setState({ matches: response.data._embedded.matches });
console.log(this.state.matches);
console.log("Dentro do didmount");
});
Everything works fine here. So in my render method i pass this data to a Match component:
var matches = this.state.matches.map(match =>
<Match key={match._links.self.href} match={match}/>
);
In my Match.js class, I try to retrieve other data with axios. But it just doesnt work. In my debug it never enters on the response function.
const awayUrl = this.props.match._links.away.href;
const homeUrl = this.props.match._links.home.href;
axios.get("http://localhost:8080/api/matches/4/away")w
.then(response => {
console.log("Dentro do away");
this.setState({ away: response.data._embedded });
console.log(this.state.away);
console.log("Dentro do away");
})
.catch((error) => {
console.log("error",error)
});
What Im missing? Theres something on the Axios lifecycle that i cant use it in the same request? Why this axios.get method is never called, and dont throws any exception too?
Thanks
In my app, I need to call several REST API endpoints:
// The UI Class
class LoginForm extends Component {
handleSubmit(){
store.dispatch(login(username, password));
}
}
// An action
function login(username, password){
return dispatch => {
fetch(LOGIN_API, {...})
.then(response => {
if (response.status >= 200 && response.status < 300){
// success
} else {
// fail
}
})
}
}
The gist is above and easy to understand. User triggers an action, an ajax call to the corresponding endpoint is made.
As I am adding more and more API endpoints, I end up with a bunch of functions similar to the skeleton of the login function above.
How should I structure my code in such a way that I don't repeat myself with duplicate ajax functions?
Thanks!
I strongly suggest you to read this popular github sample project. At first it is hard to understand but don't worry and continue to read and realize what is happening in that.
It uses very clear and simple way to handle all of your API calls. when you want to call an API, you should dispatch an action with specific structure like this:
{
types: [LOADING, SUCCESS, FAIL],
promise: (client) => client.post('/login', {
data: {
name: name
}
})
}
and it will handle these kind of actiona by a custom middleware.
The way I handle a similar situation is to have 2 wrapper for API calls:
function get(url) {
return fetch(url)
.then(response => {
if(response.status >= 200 && response.status < 300) {
return response
}
else {
let error = new Error(response.statusText)
error.response = response
throw error
}
})
.then(response=> response.json())
}
This wrapper will take a url and return the json data. Any error that happens (network, response error or parsing error) will be caught by the .catch of get
A call basically looks like that:
get(url)
.then(data => dispatch(someAction(data)))
.catch(error => dispatch(someErrorHandler(error)))
I also have a post wrapper that in addition sets the header for CSRF and cleans the data. I do not post it here as it is quite application-related but it should be quite ovious how to do it.