How to sequentially execute functions in React? - reactjs

I am trying to upload images to firebase storage and then when uploads finish, execute a try/catch block of codes with addDoc() command to create a doc inside fb database. The sample coding is as follows:
const abc = () => {
array.map(() => {
return uploadFilesToFb()
})
// then, when the above function finishes
createDocInFb()
}
I heard about Promises, but is there any other way of doing this? I mean, in firebase there are .then functions but since I have a mapping I couldn't put addDoc() after .then of uploadFilesToFb(). If only alternative is promises, how can I achieve that with promises?

Related

How We can mock test multiple api calls in jest testing

I have a scenario like i have to call 1stAPI then depending on the response of 1st API i have to call 2nd API.
I got a solution to test 1st API :
global.fetch = jest
.fn()
.mockImplementation(() => getMockPromise({ Response: resMock }));
I got my 1st response while mocking
but how can I get response in second ? I am using typescript with react
I tried to search multiple places but only got solution for one mock response only for jest testing like below :
global.fetch = jest
.fn()
.mockImplementation(() => getMockPromise({ Response: resMock }));
I thought if I use the above mockImplementation two times for different response it will work, but still same only one is working.
If you are calling fetch() with different arguments each time, you can use a mock implementation that responds with different data depending on the argument it receives.
//test file
const mockedResponses = {
'firstUrl': {}, // first response object
'secondUrl': {}, // second response object
}
global.fetch = jest
.fn()
.mockImplementation((url: string) => getMockPromise({ Response: mockedResponses[url] }));
Generally it's a good idea to have the actual fetch() call be done inside a separate function, e.g. callFirstApi() and callSecondApi(), and then you can just mock those functions instead. This also means you don't end up overwriting a global function.
You can also look into something like the Nock package which lets you do more elaborate testing of external APIs.

I am not able to set the state of locg variable from the Google api. I need to fetch multiple location latitude and longitude from the Google API

state={locg:''}
componentDidMount(){
fetch('https://maps.googleapis.com/maps/api/geocode/json?address=TajMehal&key=xxxx').then(
response=>response.json()).then
(json=>this.setState({locg:json}));
console.log('Locations from Google wdw',this.state.locg)
}
I need to create array of latitude and longitude.But for above code itself not working for hardcoded area.locg is null
The reason why you are not seeing the result on the console is because the fetch method is asynchronous. Meaning, your console log gets executed first even though it is at the end because the fetch method takes more time to finish. And since it is asynchronous, console log does not have to wait for the fetch to finish executing.
So to address this, you must use async/await. The word async before a function means one simple thing: a function always returns a promise. And the keyword await makes JavaScript wait until that promise (fetch method) settles and returns its result. This is how it should look like:
async componentDidMount() {
await fetch('https://maps.googleapis.com/maps/api/geocode/json?address=TajMehal&key=YOUR_API_KEY')
.then(response=>response.json())
.then(json=>{
this.setState({locg:json});
console.log('Locations from Google wdw',this.state.locg);
});
console.log(this.state.locg)
}
Here is a working sample for your reference: https://stackblitz.com/edit/react-async-await-63982740

Assign return value of promise to an external variable in react

I hope your are healthy and well.
I am developing a simple mobile application using ionic and react. I am using sql database and for this purpose I created Api's for user registration and login. Whenever a user login, app stores user session using local Storage. [Code for storing session]
Storage.set({
key: 'currentUser',
value: username
});
No the problem is this: [Code for retrieving stored values]
let session;
Storage.get({ key: 'currentUser' })
.then(p1 => {
const p2 = p1.value;
const p3 = p2.replace(/"/g, "");
session = p3;
});
console.log(session) //This gives 'undefined'
Here variable (p3) contains actual username. But when I assign its value to session variable. The session variable becomes undefined. I don't know how to get session value out of this function. Please help me to fix this. Thanks
I think you can't. The code wrapped in then() is executed asynchronously, meaning you don't know what is executed first: session = p3 or console.log(session).
Maybe this queestion will help?
How to access the value of a promise?
Javascript is an asynchronous language. Here your request will take some time before arriving and that's why javacript is going to ignore the function then(). You can see this process using the setTimeout function that emulate your API call:
let session;
setTimeout(() => {
// This will be executed after 500ms but javascript go ahead and execute the other console log
session = 'test';
console.log(session);
}, 500);
console.log(session) // Is executed first

How to call Square API method asynchronously

How to call paymentForm.requestCardNonce() method asynchronous
I am integrating square payment gateway in AngularJs, Now I have situation where I have to call paymentForm.requestCardNonce() and this method calls web service in background. Now I have to wait for background call than I can proceed with furthered process. So how can i handle callback from paymentForm.requestCardNonce() method which is provided by Square Payment Gateway https://docs.connect.squareup.com/payments/sqpaymentform/setup
Initialising code sample
var paymentForm = new SqPaymentForm({
applicationId: "sandbox-xxx-xxxxxxxxxxxx",
inputClass: 'sq-input',
callbacks: {
cardNonceResponseReceived: function (errors, nonce, cardData, billingContact, shippingContact) {
// I am receiving response of web service Here
}
}
}
How can I get success response in my custom function by calling method in it ?(Note - its working and calling a method also but i have to do next steps based on response from web service)
addCard = function () {
paymentForm.requestCardNonce();
// Till this function executes I need to wait here. how can I write promise here ?
}
Refrence LInks
https://docs.connect.squareup.com/payments/sqpaymentform/how-it-works
https://github.com/square/connect-api-examples/tree/master/templates/web-ui/payment-form/basic
For posterity, pulling from the comments.
requestCardNonce is asynchronous, and when it completes it will call cardNonceResponseReceived, so if you’re wanting to call a function after it’s finished, you should place it in cardNonceResponseReceived.

Trying to get ng-csv to work with Firebase

I have data stored on Firebase. I have a function that will grab the information from Firebase and return it as an array. I want to be able to use ng-csv to download that file as a .csv however when I download it is an empty file.
Is it possible to use ng-csv if I am trying to grab data from Firebase and if so does anyone have any examples?
Update (from OPs duplicate question):
I am trying to use ng-csv to allow a user to download a .csv file by clicking a button. The information is stored in Firebase and I have created a function that returns the needed information from Firebase as an array. However, I think the problem is when the button is clicked the file is downloaded before the information is pulled from Firebase and loaded, so the .csv file is always empty. Is there a way around this? Here is my code in my main.js app:
this.export = function() {
var results = fireFactory.getResults() //code that returns the array of objects
results.$loaded().then(function(array) {
var test= [];
test.push(array[0]);
test.push(array[1]);
return test;
};
};
Here is my code in my HTML file:
<button class ="btn" ng-csv="main.export()" filename="test.csv">Export</button>
Is there anyway to delay the file downloading until the information has been loaded and returned from the main.export() function?
You are almost there. Frank van Puffelen was on the right path, but stopped short of providing the fix for your code.
return test;
the above statement inside your callback is returning the result inside a promise. This results can only be consumed using promise aware code. Fortunately, ng-csv accepts a promise. If the promise is returned it should work:
this.export = function() {
var results = fireFactory.getResults()
//Here we return the promise for consumption by ng-csv
return results.$loaded().then(function(array) {
var test= [];
test.push(array[0]);
test.push(array[1]);
//the array is returned from the callback, not export
return test;
};
};
You're being tricked by the asynchronous nature in which Firebase loads data. You seem to be thinking that return test; in your original code returns a value from the export function. But if you look more carefully you'll notice that you're actually returning from the (anonymous) callback function.
It's a bit easier to see this, if we separate the callback function out and add some logging statements:
function onDataLoaded(array) {
console.log('Got results from Firebase');
var test= [];
test.push(array[0]);
test.push(array[1]);
return test;
};
this.export = function() {
console.log('Starting to get results from Firebase');
var results = fireFactory.getResults() //code that returns the array of objects
console.log('Started to get results from Firebase');
results.$loaded().then(onDataLoaded);
console.log('Registered result handler');
};
When you call fireFactory.getResults() Firebase will start downloading the data from its servers. Since this may take some time, the downloading happens asynchronously and the browser continues executing your export function, which registers a callback that you want invoked when the data from Firebase is available.
So you'll see the following output in the JavaScript console:
Starting to get results from Firebase
Started to get results from Firebase
Registered result handler
Got results from Firebase

Resources