Setting a property on the first invocation of its getter in TypeScript

Recently, I centralized duplicate code into a common service that efficiently handles retrieving a user's permissions. The idea is that upon instantiation of the service, it contacts our identity server to obtain the user's permissions and caches them for future use. This way, subsequent permission checks from components utilize the cached data instead of bombarding the identity server and causing delays in the user experience.

I am currently loading permissions within the service's onInit method, keeping track of whether the process is complete using a specific flag.

To implement this functionality, I attempted something like the following:

private isDataLoaded: boolean = false;

public userHasPermission(permissionName: string): boolean{
   while(!this.isDataLoaded)
   {
       // Implement logic to synchronously wait/sleep for a second before rechecking
   }
   return userPermissions[permissionName] == true;
}

However, I'm struggling to find a way to make the thread sleep synchronously. Most solutions I've come across involve asynchronous methods which use promises when the operation completes...which doesn't align with the requirements of this scenario. How can I achieve synchronous sleep

Answer №1

Seeking an alternative to .Result in C#, I aim to wait for the results within this call without the need to set up promise-to-result conversion at each method invocation.

The recommended approach in modern JavaScript (or TypeScript) is to utilize promises, but using async/await instead of traditional callback methods.

private isDataLoaded: boolean = false;

public async userHasPermission(permissionName: string): Promise<boolean> {
// −−−−^^^^^−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^−−−−−−−^
   while(!this.isDataLoaded)
   {
       await /* the thing that does the load and returns a promise */;
// −−−−^^^^^
   }
   return userPermissions[permissionName] == true;
}

When implementing this code, it should be within an async function and utilized as follows:

if (await userHasPermission("read")) {
    // Read something...
}

The asynchronous nature must be maintained throughout the execution chain. Rejections will automatically propagate like errors in synchronous code, requiring no additional handling except at the top-level entry point where you cannot use an async function. In such cases, handle any errors with

.catch(error => { /*...handle/report error...*/ });

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

Angular API snapshot error: The type 'IJobs' does not match the expected type 'IJobs[]'

Currently, I am in the process of learning and attempting to construct a job board using Angular 10. Although my API setup seems to be functioning properly, when navigating to the job detail page on Chrome, an error is displayed: ERROR in src/app/job-det ...

Optimizing Node Docker Build and Production Container Strategies

Currently, I am working on a Node project that utilizes MongoDB. In order to conduct automated testing, we have implemented the use of Mongo Memory Server. However, we have encountered an issue where Mongo Memory Server does not support Alpine, therefore ...

The Angular-slickgrid is encountering an issue where it is unable to access the property "hostView" as it

Hey there developers, I've been experimenting with the angular slickgrid library and attempting to incorporate the rowDetailView feature it offers. The issue I'm facing is that while I can expand the view by clicking on it, I'm unable to c ...

Applying ngClass to a row in an Angular material table

Is there a way I can utilize the select-option in an Angular select element to alter the css-class of a specific row within an Angular Material table? I have successfully implemented my selection functionality, where I am able to mark a planet as "selecte ...

Passing data from the front-end of an Angular component (app.component.html) to the back-end of another component (other.component.ts)

Imagine a scenario involving basic crud operations. Within the app.component.html file, there are multiple input fields and buttons. Upon clicking a button in app.component.html, the value of an HTML field is sent to the 'other.component.ts' comp ...

What is the best way to determine if a user is currently in a voice channel using discord.js?

Is there a way for me to determine if a user is currently linked to a voice channel? I am trying to implement a command that allows me to remove a user from a voice channel, and here is how I am attempting to check: const user: any = interaction.options.ge ...

Having constant problems with ngModel twoway binding. Any suggestions on how to successfully bind to a property in order to update an api link?

I am attempting to implement two-way binding in order to dynamically change the API endpoint when a button is clicked. The value attribute of the button should be used as part of the API URL string. I tried following an example in the Hero Angular App, bu ...

Tips for resolving conflicts between sequelize and angular within a lerna monorepo using typescript

Managing a monorepo with Lerna can be quite challenging, especially when working with both Node.js and Angular in the same project. In my setup, Angular is using "typescript": "~3.5.3". For Node.js to work seamlessly with Sequelize, I have the following ...

Angular Material Datatables - Issue with Paginating Data from Firestore

Data has been retrieved from Firestore and transformed into an Observable array with the InvoiceItem type. The data loads correctly onto the datatable, but there seems to be an issue initializing the paginator with the array's length. This could poss ...

The data retrieved from the function is classified as an indeterminate type - functions version 9

I'm currently working with a cloud function that takes an email as input and then returns the user information, which includes the uid. The declaration of the function looks like this: const getUserByEmail = httpsCallable(functions, 'getUserByE ...

Encountering an issue with MUI 5 where it is unable to access properties of undefined when utilizing makestyles

I recently finished building a react app using MUI-5 and everything was running smoothly. However, I've encountered a strange issue where my app refuses to start and I'm bombarded with multiple MUI errors. These errors started popping up after I ...

Obtaining parameters from a URL using C# and AngularJS

I'm encountering difficulties when trying to fetch parameters from my API URL. Any assistance would be highly appreciated. This is the C# code snippet [Route("api/[controller]")] public class PasswordController : Controller { private re ...

Creating a dynamic type class in TypeScript that can inherit characteristics from another class

Can a wrapper class be designed to dynamically inherit the properties of another class or interface? For instance... interface Person { readonly firstName: string; readonly lastName: string; readonly birthday?: Date } class Wrapper<T> { ...

Typescript feature: Configuring BaseUrl with nested directories

When utilizing the 'baseUrl' property along with the 'paths' property in this manner: "baseUrl": "./src", "paths": { "app-component": [ "app/app.component"], "test-component": [ "app/test/test.component" ] } the compilation proces ...

Vuejs fails to properly transmit data

When I change the image in an image field, the new image data appears correctly before sending it to the back-end. However, after sending the data, the values are empty! Code Commented save_changes() { /* eslint-disable */ if (!this.validateForm) ...

How can a custom event bus from a separate account be incorporated into an event rule located in a different account within the CDK framework?

In account A, I have set up an event rule. In account B, I have a custom event bus that needs to act as the target for the event rule in account A. I found a helpful guide on Stack Overflow, but it was specific to CloudFormation. I am providing another a ...

AngularTS - Using $apply stops the controller from initializing

Every time I launch the application, the angular {{ }} tags remain visible. Removing $scope.$apply eliminates the braces and displays the correct value. I am utilizing Angular with Typescript. Controller: module Application.Controllers { export class Te ...

Unable to retrieve the request body with bodyParser

I am currently working on a NextJS React Application. Within my server/index.tsx file, I have the following code: import next from 'next'; import express from 'express'; import compression from 'compression'; import bodyParser ...

Pointer Cursor in CSS

I am experiencing a strange issue. When I set the cursor attribute value directly as a string like return ( <Grid item> <Card sx={{ padding: "1rem", ":hover": { cursor: "pointer" ...

Unlocking the accordion feature in Ionic 3 form: A step-by-step guide

I am currently working on a search form and want to incorporate it within an accordion so that users can simply click to expand the form. Below is the code snippet: TS. buildForm(): void { this.form = this.fb.group({ username: new FormControl(& ...