Using the return statement to set a value from a callback function in TypeScript

As I retrieve data from an array of class People, each person has an attendance list represented by Observable<any[]>.

// Defining the Person class
class Person {
   id: number;
   name: string;
   attendance: Observable<any[]>; // Represents an Observable array
}

// Creating an array of People (for simplicity)
people = Person[] = this.someService.getPeople(); 

My current task involves checking if any individuals in the group have an empty attendance list, assuming that

attendance: Observable<any[]>
will be an empty array [] when no data is found. The goal is to return true or false depending on the outcome of the validation within the validateAttendance() method.

validateAttendance(): boolean {

    // Loop through each person in the array to access their attendance list.
    people.forEach(p => {
       // Using a callback function to retrieve the list.
       const func = (callback: (data) => void) => {
            // Subscribing to get the attendance data
            p.attendance.subscribe(list => {    
                callback(list);
            });
        }

       // Attempting to retrieve and check the list using the callback function
       // The issue arises as the 'result' variable turns out to be undefined.
       const result = func(res => {
           console.log(res); // Displays the attendance list for a given person
           return res;
       });

       if (result.length <= 0) {
           alert(`${p.name} has no attendance recorded - they might need a gentle nudge!`);
           return false;
       }
    });

    return true;
}

To resolve this, I experimented with incorporating a callback function inside the validateAttendance() method to obtain the attendance list and return it. Unfortunately, the 'result' variable remained undefined!

Is there a way to successfully return a value from a callback function in this scenario?

Answer №1

Here are a few issues with your current code:

  1. The code is asynchronous, so the function should also be async using Promise.
  2. The func() does not return a value, resulting in the result always being undefined.
  3. You have an alert() call within your logic. This may cause multiple pop-ups for each person without attendance, it's better to separate logic and UI concerns.

I've made some modifications to your code as follows:

function validateAttendance(people): Promise<boolean> {
  return getPeopleWithNoAttendance(people)
    .then(peopleWithNoAttendance => {
      if (peopleWithNoAttendance.length > 0) {
        // or loop through them
        alert(`${peopleWithNoAttendance[0].name} has no attendance, must be a lazy one please check.`);
        return false
      }
      return true
    })
}

function getPeopleWithNoAttendance(people) {
  return Promise.all(people.map(person => {
    return new Promise(r => {
      person.attendance.subscribe(r)
    }).then(attendance => {
      return attendance.length <= 0 ? person : undefined
    })
  })).then(listOfPeopleOrUndefined => {
    const listOfPeople = listOfPeopeleOrUndefined.filter(p => p)
    return listOfPeople
  })
}

Additionally, I've updated the code to pass the people variable. If this function belongs within a class, you can make adjustments accordingly.

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

What is the correct way to insert a new key-value pair into an object within the state of functional components?

Is there a way to dynamically add key-value pairs to the initial state of an empty object in functional components, similar to computed property names in class components? I currently have an initial state of {}. const [choice, setChoice] = useState({}) ...

Developing a Simple Analytics Dashboard

As I plan to develop a fundamental Analytics page to delve deeper into Javascript, AJAX and alternative data storage methods like redis, I find myself pondering the optimal way to deliver user data. Should it be dynamically calculated at real-time for gr ...

Is there a way to decrease the speed of a range slider?

Recently, I created a range slider using HTML, CSS, and JS to complement my Lua Nui. It's been working smoothly for the most part, but I've noticed an issue when sliding too quickly on the slider. As I slide it to the left, certain values fluctua ...

Utilizing mailerlite popups within a Next.js application: A step-by-step guide

Trying to include a mailerlite popup in a client's next.js project has been quite challenging for me. I am struggling to convert the JavaScript snippets into jsx in order to make the popups work smoothly. Everything seems to function properly on initi ...

Extracting changes from a ValueChange event in Angular Forms

Currently, I am utilizing Angular's Reactive Forms and I am in the process of incorporating an Undo/Redo functionality. My goal is to combine consecutive modifications on the same field into a single undo action. To achieve this, I believe I will nee ...

Changing the base URL in an Angular HTTPclient GET request for custom endpoint

When attempting to send a GET request to a specific URL, I'm encountering an issue where the original URL is being replaced by a different one, leading to a request being made to a non-existent URL. Below is the code snippet: import { HttpClient } f ...

AngularJS is throwing an error claiming that the controller is not defined and is not a function

Struggling to create a basic angular application, every time I attempt it, I encounter this issue and can never find a solution. The content of App.js is as follows: angular.module('Euclid', ['ui.bootstrap', 'ngRo ...

Issue in Angular Material: The export 'MaterialComponents' could not be located in './material/material.module'

I'm relatively new to Angular and I am encountering some difficulties when trying to export a material module. The error message that appears is as follows: (Failed to compile.) ./src/app/app.module.ts 17:12-30 "export 'MaterialComponents&ap ...

Is it feasible to showcase collections from MongoDB and every individual element from all collections on a single EJS page?

I am currently working on developing a forum for my website using NodeJs, Express, MongoDB, and EJS for HTML rendering. However, I encountered an error message saying: "cannot set headers after they are sent to the client." I am a bit confused about this i ...

"Why does the function not work inside the template, but works when the logic is set inside the template

My logic was working perfectly -> for example: Everything was working fine until I tried to set my values inside ts and switch logic in ts.file component. But when I did it inside the ts file, it stopped working: It's not working anymore. Why i ...

Safari-exclusive: Google Maps API dynamically altering page aesthetics post-loading

Recently, I encountered a peculiar problem. Upon loading a page, the text displayed with full opacity. However, upon the Google Maps API loading after 2 seconds, the entire page's styling suddenly changed. It was as if the text on the page became less ...

What sets typescript apart when using a getter versus a regular function?

Imagine having a class with two methods declared for exclusive use within that class. // 1. private get something() { return 0; } // 2. private getSomething() { return 0; } While I am familiar with getters and setters, I'm intrigued to know if ther ...

The Response.Write function is not functioning properly in the production environment

I have created a C# WebService (ASMX) with the code snippet below: if (!SomeValidation()) { //context.Response.ContentType = "application/json"; //context.Response.ContentType = "text/plain"; context.Response.ContentType = "application/text"; ...

Display <video> component using Angular 2

When attempting to display videos sourced from an API link, I encountered a problem where only the player was visible without the actual video content. The navigation controls of the player were also unresponsive. Interestingly, when manually inputting the ...

What is the best way to display an alert when the button is clicked repeatedly?

Is it possible to keep displaying the alert every time we click the button, rather than just once after clicking it? I currently have an alert set to trigger when a button is clicked, but it disappears after 3 seconds. How can I make it show up again with ...

How does the Cluster module in Node.js compare to the Cluster module in Learnboost?

Node.js features its own Cluster core module (source: http://nodejs.org/docs/v0.8.3/api/cluster.html) while Learnboost has introduced a similarly named Cluster module as well (source: , https://github.com/LearnBoost/cluster). What are the differences betw ...

Issue with DTO and a custom decorator in NestJS

I am currently facing an issue with using a DTO alongside a custom decorator within a NestJS controller for body validation. I am sending a request using multipart/form data, which requires me to parse the data from a string to JSON. However, when attempti ...

Steps for submitting a form once all inputs have been verified

$('#f_name, #l_name').change(function(){ if($(this).val().length < 2) { $(this).css('border', '1px solid red'); alert('names must be at least 2 symbols'); check ...

The use of Buffer() is no longer recommended due to concerns regarding both security vulnerabilities and

I'm encountering an issue while trying to run a Discord bot. The code I'm using involves Buffer and it keeps generating errors specifically with this code snippet: const app = express(); app.get("/", (req,res) => { if((new Buffer(req.quer ...

Utilizing Dual Destructuring for Handling Undefined Main Objects

Before we proceed, I want to clarify that my question is not a duplicate of ES6 double destructure Let's examine the code snippet related to Apollo Client GraphQL: import { gql, useQuery, useMutation } from '@apollo/client'; ... const { loa ...