How to extend the ion-loading till page renders in ionic-5 - ionic5

I've to make 3 back-end api-call before showing the UI screen. So, I used the ion-loading below snippet,
I'm presenting the loader in 1st backend call and it get closed in the first call itself. But I've to close the loader in third api call to show the screen.
How to extend the loader till the last api call,
this.presentLoading();
async presentLoading() {
this.loading = await this.loadingController.create({
spinner: null,
cssClass: 'custom-class custom-loading',
});
await this.loading.present();
}

One way to accomplish this would be to call .then() on loadingController.create() and then process all your api calls inside there. Here's how I would organize it so that your loading controller is dismissed properly either when the 3 api calls succeed or when one of them fails. This setup assumes your api call functions return promises.
this.loadingController.create({
message: 'Loading, please wait...'
}).then((loading) => {
loading.present();
Promise.all([apiCallOne(), apiCallTwo(), apiCallThree()])
.catch((err) => {
console.log(err);
loading.dismiss();
})
.then((results) => {
// do something with results ...
loading.dismiss();
});
});

Related

Cypress stubbing XHR response based on request

I am beginer in Cypress and looking for help with network stubbing.
My UI tiggers 3 API calls concurrently upon clicking on a button in the UI. All 3 API are of same endpoint, BUT each of them have different request and response.
I am able to stub the json response using cy.fixture, cy.server() and cy.route().
My need is to 'only stub the 3rd XHR call response', but, my test stubs all three because of the same endpoint.
Any suggessions on how could I test it using any condition ? example - Only stub the call if the parameters of 'request'XHR is 'XXX'?
I tried using before and after the .click() of submit button but that didn't work.
cy.fixture('myfixture').then(jsonresponse => {
function FixtureController(request, response) {
if (cy.url().request.body.contains("XXX")) {
cy.server()
cy.route('POST', 'URL', jsonresponse).as('myalias')
I appreciate any support.
Thanks!
You can use cy.intercept to match based on several things, including query parameters.
cy.intercept({
url: 'http://example.com/search*',
query: { q: 'expected terms' },
}, { fixture: 'myfixture' } )
If you need to match on the request body contents, you can use a route handler to specify.
cy.intercept('http://example.com/search*', (req) => {
if (req.body.contains('some string') {
req.reply({ statusCode: 200, fixture: 'myfixture' });
} else {
req.reply(); // not providing any input forwards the request as normal
}
});
Check out the cy.intercept documentation for more info.

What does status=canceled for a resource mean?

So I have an issue on local When I make a request I get the data, on Dev/QA/Prod nothing comes back I checked the network dev tools on my browser and I see that the request is being cancelled
So this happens when you return/reload window before the call finishes (the API call made is still being processed and has not completed).
onRemove = (evt) => {
evt.preventDefault();
evt.stopPropagation();
this.props.onRemove(this.props.item);
window.location.reload(); // this will cancel the call and your request wont
//be execute.
}
Removing this will sort the issue ->
" window.location.reload();"
The best thing to do is to make sure that you wait for the request to be processed before you do any other thing.
onRemove = (evt) => {
evt.preventDefault();
evt.stopPropagation();
this.props.onRemove(this.props.item);
}

Load data from Firebase Firestore to array - angularjs

I'm trying get data from firestore. Connection is ok, data is downloading but with problems.
I'm based on https://firebase.google.com/docs/firestore/query-data/get-data example.
let list = [];
let products = function GetCollection() {
firestore.collection("products")
.get()
.then(function (querySnapshot) {
querySnapshot.forEach(function (doc) {
console.log(doc.id, " => ", doc.data());
list.push(doc.data());
});
$scope.collection = list;
});
}
products();
console.log("test");
After run this code, my list is empty but in console are listed all entries. During debuging i noticed that last line with console.log("test") is executed before all body of GetCollection() function.
This is problem with sync? Can anyone help me?
yes this is expected behavior, console.log("test"); will be executed first. Because part .then(function (querySnapshot is a asynchronous call, what you are passing inside .then is a javascript promise, and that is asynchronous
you should also use handle error as mentioned in below line
.get(some comde). then ( function -- ). catch ( function (error) { console.log("Error getting cached document:", error); } )
for testing purpose, you can use firebase synchronous version of method as well, generally firebase api have corresponding sync version of method, and if I remember correctly those are suffixed with "sync"

Setting Variable to Axios Call

In React, I am trying to set a variable to an axios call after I return the data.
But, when console logging the variable afterwards, it's a Promise.
How do I get the value from the promise and set it to the variable?
let fourPackProducts = axios.get('URL').then(response => {
return response.data })
console.log(fourPackProducts)
Console log screenshot
You did exactly what you are asking to do. If you want to console.log the correct data, chain another then like so,
let promiseResponse = axios.get('URL')
.then(response => response.data)
.then( data => { console.log( data ); return data });
Remember, ajax requests are async, so code after an ajax request not using async handlers will run, the compiler does not stop and wait for the request to complete
You're console logging a promise because fourPackProducts is a promise. Another part of the issue is that since the promise is asynchronous, the console log is being called before the promise response comes through. To properly set the promise response to a variable, try the following:
let promiseResponse;
let fourPackProducts = axios.get('URL').then(response => {
promiseResponse = response.data;
console.log(promiseResponse);
return promiseResponse;
})
Presumably you want to do something with this variable afterward, but if the promise is not yet completed then the variable will be undefined. In order to use the variable after it has been set to the promise response, you will need to chain promises.

Is it possible to make a pseudo-global promise rejection handler?

fetch() is a great improvement over the classic XMLhttpRequest() However I was wondering if I add window.addEventListener('unhandledrejection', event => ยทยทยท); to my index.android.js and index.ios.js could I theoretically remove all of my .catch() from my promise chains and make a pseudo global promise rejection handler? I am building a react native app that relies heavily on api calls, many of which are authenticated with user tokens. When a user logs in a token is stored in asynchronous storage, but each token will expire after a certain amount of time. if a user opens the app and unwittingly attempts to make a call that requires authentication with an expired token I would like the user to be routed to the login page regardless of what call was made, or what component the call is in. I currently have each individual promise chain handling unauthenticated calls on their own. Is there a better way to do it?
You could make a custom abstraction on top of fetch, which will provide a way of communicating with API and also have some business logic, which for you case is to request an auth token or make a redirect. Then you use this abstraction in the rest of the code to make API calls. Here is a small example to demonstrate the idea:
export default function request(url, options = {}) {
const req = fetch(url)
.then((response) => {
// Global response handler
// ...
// Hand response down the promise chain
return response;
})
.catch((err) => {
// Global error handler
// Check error status and (make redirect/request auth token)
// Throw error down the promise chain if needed
throw err;
});
// Returns a promise
return req;
}
Then you use it in your code like fetch(), but instead you'll be able to modify and extend it for you needs any time.
request('http://example.com/api/post/1')
.then((response) => {
// "response" has whatever you returned from global handler
})
.catch((err) => {
// "err" is whatever you've thrown from global handler
});

Resources