Async and Await with Typescript

After searching extensively, I couldn't find a similar issue. I am working with Ionic 4 in Angular 7 along with Typescript 3.16. I have multiple 'TimeSpan' values that I need to retrieve using a function from the HTML like so:

<ion-input type="text" (click)="getTypTime()" ....>

Here is the click handler function:

getTypTime() { // Retrieves the typical time
  const currentTime = this.service.TimeToDoTypicalOrBestCase;
  this.getTime(currentTime).then( res => {
  console.log('GetTypTime result :');        // **3**
  console.log(res);
  });
}

The function responsible for presenting the picker and retrieving the result looks like this:

async getTime(inputTime: TimeSpan) {
console.log(inputTime);             // **1**
const opts: PickerOptions = {
  buttons: [
        ...more stuff...
  ],
  columns: [
    {
      name: 'Hours',
        ...more stuff...
      ]
    },
    {
      name: 'Mins',
           ...more stuff...
    }
  ]
};
const picker = await this.pickerCtrl.create(opts);
console.log('Presenting picker');             // **2**
picker.present();
picker.onDidDismiss().then(() => {
  picker.getColumn('Hours').then( colh => {
    this.pickedTime.hours = colh.options[colh.selectedIndex].value;
    picker.getColumn('Mins').then( colm => {
    this.pickedTime.minutes = colm.options[colm.selectedIndex].value;
    console.log(this.pickedTime);             // **4**
    return this.pickedTime.ToString();
    });
  });
 });
}

The log outputs:

00:30:00                       (This is at the beginning of the function **1** as per code)
Presenting picker              (This appears towards the end of the function **2**)
GetTypTime result : undefined  (This is in the CALLING function **3**)  
(The following line displayed after the dismiss **4**) 
TimeSpan {_seconds: 0, _minutes: 0, _hours: 0, _ days: 0, _milliseconds: 0, …}

It seems like the function is returning before completing the ondismiss action of the picker. Any idea where the issue lies..?

I had previously used await within the picker's onDidDismiss, like this:

  picker.onDidDismiss().then(async () => {
  let col = await picker.getColumn('Hours');
  this.pickedTime.hours = col.options[col.selectedIndex].value;
  col = await picker.getColumn('Mins');
  this.pickedTime.minutes = col.options[col.selectedIndex].value;
  console.log(this.pickedTime);
  return this.pickedTime.ToString();
});

}

However, this approach didn't work so I made modifications by removing the awaits. What are your thoughts on this..?

Answer №1

I successfully resolved the issue, although I must admit that I still don't fully grasp the problem. Nevertheless, I have provided my solution here in case it proves helpful to others facing a similar predicament.

The crux of the matter seemed to lie in the choice between using async ... await or ...then( () => {}) to manage promises. Coming from a background in C#, I am quite comfortable with async / await as it generally performs as expected. However, I encountered scenarios in TypeScript where I had to incorporate both await and .then( etc.).

In the end, I managed to resolve the issue by converting everything to use await consistently, even extending it to the calling function. This snippet did the trick:

const picker = await this.pickerCtrl.create(opts);
await picker.present();
await picker.onDidDismiss();
const colh = await picker.getColumn('Hours');
this.pickedTime.hours = colh.options[colh.selectedIndex].value;
const colm = await picker.getColumn('Mins');
this.pickedTime.minutes = colm.options[colm.selectedIndex].value;
return this.pickedTime.ToString();

This addressed the ordering problem, although initially it was returning undefined when called from the following function:

  getTypTime() { // Gets the typical time
    const currentTime = this.service.TimeToDoTypicalOrBestCase;
    this.getTime(currentTime).then( res => {
    console.log('GetTypTime result :');
    console.log(res);
    });
  }

The output showed undefined until I made the adjustment to:

  async getTypTime() { // Gets the typical time
  const currentTime = this.service.TimeToDoTypicalOrBestCase;
  const res = await this.getTime(currentTime);
  console.log('GetTypTime result :');
  console.log(res);

}

This modification led to everything functioning correctly.

I appreciate those who offered assistance along the way.

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

End the primary division post button activation within Angular 2

Is there a way to close the main div upon clicking a button that is located inside the same div? Below is my code snippet: index.html <div id="main"> <button type="button">Click Me!</button> </div> hello.component.ts import ...

Discover the contents of an Object's key in TypeScript

I currently have a variable of type object. let ref_schema_data: object The value of ref_schema_data: { '$schema': 'http://json-schema.org/draft-07/schema', '$id': 'tc_io_schema_top.json', allOf: [ { type: &a ...

Error: The jasmine framework is unable to locate the window object

Currently, I am testing a method that includes locking the orientation of the screen as one of its functionalities. However, when using Jasmine, I encountered an error at the following line: (<any>window).screen.orientation.lock('portrait&apos ...

Launch a fresh window in Angular application without the need for a complete restart

How can I open a new window in Angular while passing values in the route to call an endpoint without causing the entire application to reload? It feels like such a hassle just to display a simple HTML page. Is there a better way to achieve this? ...

The Angular TypeScript service encounters an undefined issue

Here is an example of my Angular TypeScript Interceptor: export module httpMock_interceptor { export class Interceptor { static $inject: string[] = ['$q']; constructor(public $q: ng.IQService) {} public request(config: any) ...

Is it possible for the ionic ionViewDidEnter to differentiate between pop and setRoot operations?

I am facing an issue with my ionic 3 page where I need to refresh the data on the page only if it is entered via a navCtrl.setRoot() and not when returned to from a navCtrl.pop(). I have been using ionViewDidEnter() to identify when the page is entered, bu ...

Attempting to retrieve data either by code or with a WHERE condition proves unsuccessful as the data retrieval process yields no results

Seeking assistance with my Angular project that is utilizing a Node.js server and MSSQL express. I am having trouble retrieving data using a WHERE condition in my code. Any help in identifying the missing piece or error would be appreciated. Thank you. // ...

Is there a way to restrict an array to only accept distinct string literals?

export interface IGUser { biography: string; id: string; ig_id: string; followers_count: number; follows_count: number; media_count: number; name: string; profile_picture_url: string; shopping_product_tag_eligibility: boolean; username: ...

In Angular with rxjs, make sure the response is set to null if the json file cannot be found during an http.get request

When working on my Angular app, I often retrieve data from a static JSON file like this: @Injectable() export class ConfigService { constructor(private http: HttpClient) { } getData() { this.http.get('/assets/myfile.json').subscribe(da ...

Seeking a quick conversion method for transforming x or x[] into x[] in a single line of code

Is there a concise TypeScript one-liner that can replace the arrayOrMemberToArray function below? function arrayOrMemberToArray<T>(input: T | T[]): T[] { if(Arrary.isArray(input)) return input return [input] } Trying to cram this logic into a te ...

Refreshing a page in Angular 2 using webpack may sometimes lead to the index.html file loading without any styling or

I'm having trouble with my Angular 2 project. Every time I refresh the page or the HRM does, it redirects to index.html (or '/') without injecting the html code and webpack head-config.common.js properly. Additionally, I noticed that the web ...

Positioning the box at the exact middle of the screen

I'm trying to center an item on the screen using material ui, but it's appearing at the top instead of the middle. How can I fix this? import * as React from 'react'; import Box, { BoxProps } from '@mui/material/Box'; functio ...

Unable to loop through the "dataList" retrieved from a service call to the java backend within an Angular 9 application

After receiving JSON data from a Java backend service called houseguidelines, the information is sent to an Angular application via a service call. I am attempting to iterate over this returned JSON data and add it to an array I have created. Unfortunately ...

Is the 'case' in a switch statement not treated as a typeguard by Typescript?

Here is a simplified version of the code I am working with: type Todo = { id: string; text: string; }; type Action = | { type: 'DELETE'; payload: string } | { type: 'CREATE'; payload: Todo } function reducer(state: Todo[], ...

Encountering issues with MediaSession.setPositionState() and seekto functionalities not functioning properly

Having trouble with MediaSession.setPositionState() not displaying the audio time and seekbar not behaving as expected. const sound= document.querySelector('sound'); function updatePositionState() { if ('setPositionState' in navigato ...

Ways to implement distinct values for model and input field in Angular 5

I'm currently working on an Angular 5 application and I have a requirement to format an input field with thousand separators (spaces). However, the model I am using only allows numbers without spaces. Since my application is already fully developed, ...

Encountering difficulties retrieving information from an API using Angular

I am encountering an issue while trying to retrieve data from an API. When I use console.log() to view the data, it shows up in the console without any problem. However, when I attempt to display this data in a table, I keep receiving the error message: ER ...

In my Ionic/Angular project, I'm attempting to showcase two columns side by side in a row. However, the layout seems to be stacking them on top of each other with the

I am having some trouble arranging two columns in a row for my Ionic/Angular project. It seems like the content is stacking on top of each other instead of side by side. Here's the CSS I'm using: <ion-grid class="rewards-container&q ...

Filtering a Table with Angular Material: Using multiple filters and filter values simultaneously

Looking to implement dual filters for a table of objects, one being text-based and the other checkbox-based. The text filter works fine, but struggling with the checkbox filter labeled "Level 1", "Level 2", etc. Ideally, when a checkbox is checked, it shou ...

What is the best way to validate the Click outside directive in Angular applications?

Exploring the click-outside directive for testing purposes. It seems that there is an issue with ignoring a specific div element while clicking outside. import { Directive, ElementRef, Output, EventEmitter, HostListener } from '@angular/core'; ...