What is the best way to create a linear flow when chaining promises?

I am facing an issue with my flow, where I am utilizing promises to handle the process.

Here is the scenario: The User clicks a button to retrieve their current position using Ionic geolocation, which returns the latitude and longitude. Next, I aim to decode these coordinates to obtain the City, and finally, set the latitude, longitude, and city for the user.

tryGeolocation() {       
    this.geolocation.getCurrentPosition().then((resp) => {
      let pos = {
        lat: resp.coords.latitude,
        lng: resp.coords.longitude
      };
      this.lat = resp.coords.latitude;
      this.long = resp.coords.longitude;          
      console.log(this.lat+"--"+this.long);
      this.decodeCoord(this.lat, this.long);
      alert(this.city);
      this.uploadLocation();    
    }).catch((error) => {
      console.log('Error getting location', error);
      this.loading.dismiss();
    });
  }



 decodeCoord(lat, long) {    
    console.log("decodeCoord");
    var latlng = new google.maps.LatLng(lat, long);
    this.geocoder.geocode({'latLng': latlng}, function (results, status) {
      if (status == google.maps.GeocoderStatus.OK) {       
        if (results[1]) {
          var indice = 0;
          for (var j = 0; j < results.length; j++) {
            if (results[j].types[0] == 'locality') {
              indice = j;
              break;
            }
          }   

          let city, region, country;
          for (var i = 0; i < results[j].address_components.length; i++) {
            if (results[j].address_components[i].types[0] == "locality") {
              //this is the object you are looking for City
              city = results[j].address_components[i];
            }
            if (results[j].address_components[i].types[0] == "administrative_area_level_1") {
              //this is the object you are looking for State
              region = results[j].address_components[i];
            }
            if (results[j].address_components[i].types[0] == "country") {
              //this is the object you are looking for
              country = results[j].address_components[i];
            }
          }
          //city data        
          this.city=city;
        } else {
          console.log("No results found");
        }           
      } else {
        console.log("Geocoder failed due to: " + status);
      }
    });      
  }



uploadLocation() {   
    let position = {
      latitude: this.lat,
      longitude: this.long,
      city: this.city
    }  
    this._us.updateUserIndividual(position).then(data => {      
      console.log("USER UPDATED");
    }).catch((err) => {
      this.presentToast("Ups! Ha ocurrido un Error, intentalo otra vez");
    })
  }

I have attempted to include

this.decodeCoord(this.lat, this.long);
in uploadLocation(), but it does not work either.

The issue persists as the city always remains empty.

Answer №1

The value within this.city is currently empty due to the assignment being made within a separate context of this. This issue arose when you created a new context by defining this.geocoder.geocode() using the function keyword for the callback function. By switching to an arrow function, you should be back on track:

this.geocoder.geocode({'latLng': latlng}, (results, status) => {
  // ...
});

However, things are not quite that simple.

this.decodeCoord(this.lat, this.long);
alert(this.city);

This approach won't be effective because the modified callback function is asynchronous by nature. Therefore, it would be best to have the decodeCoord method return a Promise:

decodeCoord(lat, long) {    
  return new Promise((resolve, reject) => {
    // ...
    this.geocoder.geocode({'latLng': latlng}, (results, status) => {
      if (status == google.maps.GeocoderStatus.OK) { 
        // ...
        resolve();
      } else {
        reject();
      }
    });
  });
}

Furthermore, you need to ensure that your updateLocation method also returns the promise:

return this._us.updateUserIndividual(position).

You can then update your tryGeolocation method accordingly:

async tryGeolocation() {   
  try {
    const { coords } = await this.geolocation.getCurrentPosition();
    this.lat = coords.latitude;
    this.long = coords.longitude;          

    await this.decodeCoord(coords.latitude, coords.longitude);
    alert(this.city);
    await this.uploadLocation(); 
  } catch (e) {
    console.log('Error getting location', e);
  }  finally {
    this.loading.dismiss();  
  }
}

Once these adjustments are made, your asynchronous operations should execute sequentially as intended.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Vue Application experiences issues resizing Three.js Animation in Canvas

Currently, I am deep diving into learning Three.js within a Vue.js component. Take a look at my code snippet: <script> import * as THREE from "three"; export default { name: "Scene", mounted() { this.initializeThree(); ...

Maximizing the power of datatables with ajax integration

Exploring pagination with AJAX on datatables.net is something I want to try. I have two input fields where users can enter start and end dates, followed by the table structure below: <table class="table table-hover" id="example"> < ...

Prevent the Icon in Material UI from simultaneously changing

I'm working on a table where clicking one icon changes all icons in the list to a different icon. However, I want to prevent them from changing simultaneously. Any suggestions on how to tackle this issue? Code: import React from 'react'; im ...

Leveraging shadow components with the Next.js pages directory

I am facing an issue with getting a simple shadcn button to work because I am unable to import the button. Although I am using nextjs 13, I am still utilizing the pages directory. Below is the process of how I installed shadcn. Here is the installation co ...

A guide on implementing Angular-DataTable within a TypeScript project

Hey everyone, I'm currently working on a TypeScript and Angular application. To create a data table, I decided to use Angular-DataTable. After creating a sample application using it, I added the following code to my Controller: constructor(protecte ...

Determine the shared elements within a single array by utilizing Javascript

I have the following array of mergeUniqueItems: var mergeUniqueItems = ["-JsDEcxz_ZSGFLKwd1QM", "-JsJ2NXGDYKI6QRsuXVK", "-JsJ2RK-kOG2eGcG04xF", "-JsJ2RK-kOG2eGcG04xF", "-JsJ2YLPiP6751zh8geS"] After using this code snippet, I encountered an issue: ...

If every single item in an array satisfies a specific condition

I am working with a structure that looks like this: { documentGroup: { Id: 000 Children: [ { Id: 000 Status: 1 }, { Id: 000 Status: 2 ...

"Attempting to verify a JSON Web Token using a promise that returns an object not compatible with the specified

Learning about Typescript has been quite a challenge for me, especially when it comes to using the correct syntax. I have implemented a promise to retrieve decoded content from jwt.verify - jsonwebtoken. It is functioning as intended and providing an obje ...

In Javascript, determine the root cause of a boolean expression failing by logging the culprit

Within my JavaScript code, I have a complex predicate that comprises of multiple tests chained together against a value. I am looking for a way to log the specific location in the expression where it fails, if it does fail. Similar to how testing librarie ...

The ASP.NET MVC3 form collection registers as 0 when performing a jQuery ajax post

I'm currently developing a project on ASP.NET MVC3. My current challenge involves POSTing to a method that should return a set of data using the jQuery.ajax api. However, upon handling the request on the server, I noticed that the form collection&apo ...

Using jsdom as a package in a Meteor application is not possible

Recently, I came across an issue with my packages.json file. It looks like this: { "jsdom" : "0.8.0", "request" : "2.25.0" } As part of my project, I have the following code snippet: if (Meteor.isServer) { Meteor.startup(function () { var _ ...

jQuery's element loading function fails to work with ajax requests

When trying to preload ajax data before attaching it to a div, I utilized the following code: $.ajax({ url: 'ajax.php', data: { modelID:id }, type: 'post', success: function(result){ $(result).load(function(){ ...

Troubleshooting: The reason behind my struggles in locating elements through xpath

There is a specific element that I am trying to locate via XPath. It looks like this: <span ng-click="openOrderAddPopup()" class="active g-button-style g-text-button g-padding-5px g-margin-right-10px ng-binding"> <i class=&quo ...

Reviewing the element names in a jQuery-selected array of objects

I'm new to javascript and the jquery library and I need to work with an array of input fields that have specific names for validation. Each input field is named NS[0], NS[1], etc., and the total number of these fields is generated dynamically in the c ...

What is the best way to retrieve specific information from a group of data using Mongoose?

I need assistance with extracting the number from a collection that contains only a name and a number. I also want to either change the number or store it in a variable. How can I achieve this? let dataSchema = new mongoose.Schema({ name: String ...

Evolving characteristics of Bootstrap popover

I am currently working on a text field and button setup where I have implemented a popover feature using Bootstrap. This is the code snippet I am using: function displayPopover() { $("#text").popover("show"); } The popover appear ...

I need to know how to use Axios to fetch data from multiple sources at the same time without any risk of the

Trying to initiate multiple axios operations simultaneously to fetch data from various sources at once using a loop leads to the received data getting intermingled and corrupted. Even creating distinct axios instances for each data source doesn't see ...

Experience the feeling of releasing momentum by click and dragging the scroll

One feature I am looking for is the ability to control the scroll speed when dragging, and have the scroll continue moving slightly after release instead of stopping instantly. CodePen: https://codepen.io/rKaiser/pen/qGomdR I can adjust the speed adequat ...

Below are the steps to handle incorrect input after receiving only one letter:

H-I This is my input .centered-name { width: 80%; margin: auto; } .group { width: 100%; overflow: hidden; position: relative; } .label { position: absolute; top: 40px; color: #666666; font: 400 26px Roboto; cursor: text; transit ...

Tips for Retrieving the Key Names of JSON Objects within a JSON Array

I'm trying to retrieve the object names "channelA" and "channelB". Here is the JSON data: [ { "channelA": { "programmes": [ { "start_utc": 1522208700, "stop_utc": 152220 ...