How to hide an AntD message after another Promise (API request) completes? - reactjs

I want to make an API call. When the API call started I display a loading message. I want to stop showing this message when the API call is a success.
This is the message I am using now
message.loading({
content: "Loading...",
duration: 0,});
I don't know how to stop the message when the API call is a success.

The message.loading (and other functions, like message.success, message.info, etc) return a function that closes the message-box when invoked. This is demonstrated in this sample from their docs:
const showThenHide = () => {
// This starts showing the message:
const hide = message.loading('Action in progress..', 0);
setTimeout(hide, 2500); // <-- This invokes the `hide` function after 2.5 seconds
};
showThenHide();
I assume you already have a Promise<T> that represents your API request in-progress. In which case:
const hideMessage = message.loading('Loading..', /*duration:*/ 0);
try {
const apiRequestPromise = someApiClient.doSomething();
const apiRequestRespons = await apiRequestPromise; // You can also inline this await
renderApiResponse( apiRequestRespons );
}
catch ( err ) {
// TODO: Error-handling
}
finally {
hideMessage();
}
It's important to have the hideMessage() invocation in a finally block and not just after the await apiRequestPromise because if an exception is thrown inside the try block (or if you don't have a try block at all) then the message will remain open indefinitely, which isn't what you want.

if you had checked the document of antd about message you would see how they destroy the loading message there:
message.loading(..) return hide function when excute.
to hide the loading, simply call the hide message.
so I can give you an example to handle asynchronous API call:
const hide = message.loading('Loading...',0)
API.getUser(id).then(res => {
//handle response
hide()
}

Related

trying to call api with multiple objects react JS

I'm trying to call a specific object within an api but it returns error
...
calling the first one works but when i call the second objects it returns error
here's the code
Api link : https://opentdb.com/api.php?amount=3&difficulty=easy&type=multiple
const [quiz,setQuiz] = React.useState([""])
React.useEffect(() => {
async function getQuiz() {
const res = await fetch(
"https://opentdb.com/api.php?amount=3&difficulty=easy&type=multiple"
);
const data = await res.json();
setQuiz(data.results);
}
getQuiz();
});
return (
<QuizPage
questionOne={quiz[0].question} //this works //
questionsTwo={quiz[1].question} //this not //
/>
);
I tried to create separate states but it did not work either
i tried to create a seperate state and calling a second object but that didnt work either, i also tried to map over it and still didnt work, i tried many other methods to call api but still no solutions and i get this error in the console ncaught TypeError Cannot read properties of undefined reading 'question, Consider adding an error boundary to your tree to customize error handling behavior, logCapturedError
const [quiz,setQuiz] = React.useState([""])
Your initial sate has only one element, so quiz[1] is undefined, and quiz[1].question will throw an error. You will need to check for the case where you don't have data and either show nothing, or show some loading screen. For example:
const [quiz,setQuiz] = React.useState(null)
// ...
if (!quiz) {
return <div>Loading...</div>
} else {
return (
<QuizPage
questionOne={quiz[0].question}
questionsTwo={quiz[1].question}
/>
);
}

CHROME EXTENSIONS: Message passing - chrome.runtime.sendMessage or onMessage not working

I am working on google extensions. I am trying to process message passing between my popup.tsx and background.ts
Before sending message from my background.ts, I print the data. Data exist. However, in my popup.tsx chrome.runtime.onMessage not triggered. I dont understand which function not working and what is the problem. I examine lots of example but result still the same. What is the problem? I am adding my message passing codes..
Here is my background.ts runtime.sendMessage func. this function is inside another function that is called 'collectData'. When I open new tab or update the tab, this function triggered and works. Everytime this data works stable. I can see the data in every page.
chrome.runtime.sendMessage({
msg: 'url_data',
data: data,
})
Then, I am trying to receive the data in my popup.tsx with runtime.onMessage. When I reset the extension, it works sometimes just once, then that onMessage func not working at all :
const [requestData, setRequestData] = useState<string>()
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
console.log(' popup runtime on message req', request)
if (request.msg === 'url_data') {
checkWebsite(request.data).then((res) => {
console.log('popup data alındı')
console.log('popu res', res)
setRequestData(res)
// chrome.runtime.sendMessage({
// msg: 'res_length',
// data: res.matches.length,
// })
// console.log('popup data res length gönderildi')
// res.matches.length === 0 ? setIsSecure(true) : setIsSecure(false)
setHost(request.data.hostname)
})
sendResponse({ message: 'res length sended' })
console.log('res length response send')
}
})
Everytime, I change request data state. If it changes, I want to update popup with useEffect.
useEffect(() => {
console.log('useeffect', requestData)
}, [requestData])
As a result, for the first the main problem is message passing. Why it is not working?

React Query handling response status codes

this is related to this question:
Handling unauthorized request in react-query
I understand the point that React-Query doesnt care about responses codes because there is no error. So for example if the server respond with a 400 "Bad Request", do i have to check for this on the data returned by the muate function?
const handleFormSubmit = async (credentials) => {
const data = await mutateLogin(credentials);
// Do i have to check this data if for example i wanna show an error message
// "Invalid Credentials"?
};
I need to save the user on the cache.
const useMutateLogin = () => {
return useMutation(doLogin, {
throwOnError: true,
onSuccess: data => // Do i have to check here again if i receive the user or 400 code
})
}
Thanks.
react-query does not take care of the requests and it is completely agnostic of what you use to make them as long you have a Promise. From the documentation we have the following specification for the query function:
Must return a promise that will either resolves data or throws an error.
So if you need to fail on specific status codes, you should handle that in the query function.
The confusion comes because popular libraries usually take care of that for you. For example, axios and jQuery.ajax() will throw an error/reject if the HTTP status code falls out of the range of 2xx. If you use the Fetch API (like the discussion in the link you posted), the API won't reject on HTTP error status.
Your first code snippet:
const handleFormSubmit = async (credentials) => {
const data = await mutateLogin(credentials);
};
The content of data depends on the mutateLogin function implementation. If you are using axios, the promise will reject to any HTTP status code that falls out of the range of 2xx. If you use the Fetch API you need to check the status and throw the error or react-query will cache the whole response as received.
Your second code snippet:
const useMutateLogin = () => {
return useMutation(doLogin, {
throwOnError: true,
onSuccess: data => // Do i have to check here again if i receive the user or 400 code
})
}
Here we have the same case as before. It depends on doLogin implementation.

Figma React plugin PostMessage not working as expected

I'm trying to create a plugin for Figma, which has been going fine until now. It's based on the react example they provide on their github page: https://github.com/figma/plugin-samples/tree/master/react
In this example I've created a button, that on click will call this function:
(file: ui.tsx)
onClick = () => {
parent.postMessage({pluginMessage: {type: 'GetData'}}, '*');
};
This is parent.postMessage is a function figma provides to communicate with another file in the project, code.ts. This file will receive the postMessage with the pluginMessage as parameter, which works as expected. The code.ts that receives this looks like this:
(file: code.ts)
figma.ui.onmessage = msg => {
if (msg.type === 'GetData') {
figma.ui.postMessage({"title": figma.currentPage.selection[0].name});
}
};
This file receives the message, and it gets in the if statement since GetData has been set. Up until here, everything is good and well. The issue I'm walking into is the figma.ui.postMessage({}), which should do a callback to the onmessage function in ui.tsx:
(file: ui.tsx)
onmessage = (selection) => {
console.log(selection);
};
This onmessage function should, according to Figma's documentation, receive the object from the postMessage in code.ts. This does however never happen; it will never be called at all. I can't access the current selection in ui.tsx, so I need data from code.ts. Is there any way to pass this data to ui.tsx, or does anyone know why this doesn't work?
I encountered the same issue. Within your ui.tsx file, try adding the following:
window.onmessage = selection => {
let message = selection.data.pluginMessage;
console.log(message);
}
or try this ->
window.addEventListener("message", (selection) => {
console.log(selection);
});
this will add another message event handler to the window. if you use onmessage it might overwrite the previous handler!
put first of script
onmessage = event => {
console.log("got this from the plugin code", event, event.data.pluginMessage)
}

What did I wrong in the code. I am getting late response from Axios

I am trying to validate user details in submit, calling this method from submit click
validateCredentials() {
console.log('Validateuser')
let isUserValid = false
axios.get('http://localhost:12345/api/Login/ValidateCredentials?UserID=abc&Password=abc')
.then(res=>{isUserValid = response.data.Item1})
console.log(isUserValid)
return isUserValid
}
Here isUserValid is always true from API, but first time it returns false. After login Failed getting response as True
and the output
Output console log
If you want to use the server response synchronously and assign to a variable you need to use promises or async/await
In the above code you are using a asynchronous code axios call to set the value, but will not work all the time
Use the below code to perform asynchronous task synchronously
async validateCredentials() {
console.log('Validateuser')
let isUserValid = false
let reponse = await axios.get('http://localhost:12345/api/Login/ValidateCredentials?UserID=abc&Password=abc')
isUserValid = respose.data.Item1
console.log(isUserValid)
return isUserValid
}
Also when calling the function validateCredentials use await or promise to wait till the validation is set successfully

Resources