Using a forEach loop within an Else statement is ineffective

I've encountered an issue while trying to merge two arrays and create a new one. It seems that my forEach loop inside the else statement is returning undefined. I'm unsure if I made a mistake in my approach or if forEach is not meant to be used within an else statement. If there's a better way to achieve the desired result, please advise.

stackblitz : https://stackblitz.com/edit/angular-ivy-145nbf?file=src%2Fapp%2Fapp.component.ts

public merged = [];
public ArrayOne = [
  {
    time: "05:00 PM",
    maxNumber: 4
  },
  {
    time: "05:30 PM",
    maxNumber: 4
  },
  {
    time: "06:30 PM",
    maxNumber: 4
  }
];

public ArrayTwo = [
  {
    active: 2,
    time: "05:00 PM"
  }
];


mergeArray() {
  let t = this.ArrayOne.map((element, i) => {
    let d = {
      time: element.time,
      maxNumber: element.maxNumber,
      active: this.getActive(this.ArrayTwo)
    };
    this.merged.push(d);
    console.log(d);
  });
}

getActive(arr2) {
  if (arr2.length === 0 || arr2 === null || arr2 === undefined) {
    return 0;
  } else {
    arr2.forEach((element, i) => {
      if (element.time === this.ArrayOne[i].time) {
        return element.active;
      } else {
        return 0;
      }
    });
  }
}

Expected Result

public merged = [
    {
      time: "05:00 PM",
      maxNumber: 4,
      active: 2
    },
    {
      time: "05:30 PM",
      maxNumber: 4,
      active: 0
    },
    {
      time: "06:30 PM",
      maxNumber: 4,
      active: 0
    }

];

Answer №1

If you find yourself needing to stop or break a forEach() loop, the only way to do so is by throwing an exception. Remember, if this behavior is necessary, forEach() is not the appropriate tool for the job.

Instead, consider implementing early termination using:

  • A standard loop
  • A for...of loop
  • Array.prototype.every()
  • Array.prototype.some()
  • Array.prototype.find()
  • Array.prototype.findIndex()

By choosing one of the above methods over forEach(), you will achieve the desired outcome more effectively.

Answer №2

let combinedArray = [];
let ArrayOne = [
  {
    time: "05:00 PM",
    maxNumber: 4
  },
  {
    time: "05:30 PM",
    maxNumber: 4
  },
  {
    time: "06:30 PM",
    maxNumber: 4
  }
];

let ArrayTwo = [
  {
    active: 2,
    time: "05:00 PM"
  }
];


function mergeArrays() {
  let mappedArray = this.ArrayOne.map((element, i) => {
    let data = {
      time: element.time,
      maxNumber: element.maxNumber,
      active: this.getActiveValue(this.ArrayTwo, element.time)
    };
    this.combinedArray.push(data);
    console.log(data);
  });
}

function getActiveValue(arr2, time) {
  if (arr2.length === 0 || arr2 === null || arr2 === undefined) {
    return 0;
  } else {
    const searchedElement = arr2.find(element => element.time === time);
    return searchedElement !== undefined ? searchedElement.active : 0;
  }
}

mergeArrays()

Answer №3

One way to achieve the desired outcome is by utilizing a for loop instead of a forEach loop, as the latter does not support returning values.

    import { Component, VERSION } from "@angular/core";

    @Component({
      selector: "my-app",
      templateUrl: "./app.component.html",
      styleUrls: ["./app.component.css"]
    })
    export class AppComponent {
      constructor() {}
      public merged = [];
      public ArrayOne = [
        {
          time: "05:00 PM",
          maxNumber: 4
        },
        {
          time: "05:30 PM",
          maxNumber: 4
        },
        {
          time: "06:30 PM",
          maxNumber: 4
        }
      ];

      public ArrayTwo = [
        {
          active: 2,
          time: "05:00 PM"
        }
      ];

      mergeArray() {
        let t = this.ArrayOne.map((element, i) => {
        let d = {
            time: element.time,
            maxNumber: element.maxNumber,
            active: this.getActive(this.ArrayTwo)
        };
        this.merged.push(d);
        console.log(d);
      });
    }

    getActive(arr2) {
      if (arr2.length === 0 || arr2 === null || arr2 === undefined) {
        return 0;
      } else {
        for (let i = 0; i < arr2.length; i++) {
          if (arr2[i].time === this.ArrayOne[i].time) {
            return arr2[i].active;
          } else {
            return 0;
          }
        }
      }
    }
  }

Answer №4

Summary

Providing a concise solution

mergeArray(): void {
  const t = this.ArrayOne.map((element, i) => {
    return {
      time: element.time,
      maxNumber: element.maxNumber,
      active: this.getActive(element)
    };
  });
  this.merged.push(t);
}

getActive(element: {time: string, maxNumber: number}): number {
  return this.ArrayTwo
  ?.find(e => e.time === element.time)
  ?.active ?? 0;
}

Explanation

Your code contains multiple errors and practices that are not optimal. Even though some of the issues have been resolved in the suggested solution above, I will refrain from discussing all of them in detail here.

Your original code:

mergeArray() {
  // t will be void[]
  let t = this.ArrayOne.map((element, i) => {
    let d = {
      time: element.time,
      maxNumber: element.maxNumber,
      active: this.getActive(this.ArrayTwo)
    };
    this.merged.push(d);
    console.log(d);
    // missing return value
  });
}
  1. The callback function within map does not return any values, resulting in an array of undefined items for t: see Array.prototype.map
  2. Passing one instance field (ArrayTwo) as an argument to another instance method (getActive) is unnecessary since the method already has access to the field.

Your original code:

getActive(arr2) {
  // `arr2` would be falsey if it is null or undefined,
  // no need to check for each specifically
  if (arr2.length === 0 || arr2 === null || arr2 === undefined) {
    return 0; // if returning from within an `if` statement...
  } else {    // the `else` is redundant
    // what if `arr2` has more elements than `ArrayOne`? -> exception!
    for (let i = 0; i < arr2.length; i++) {
      if (arr2[i].time === this.ArrayOne[i].time) {
        return arr2[i].active;
    } else {  // again `else` is redundant
      return 0;
    }
  }
}

It seems unnecessary to search by index based on logic alone

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

Typescript is struggling to locate a module that was specified in the "paths" configuration

Within my React project, I have set up a module alias in the webpack config. Now, I am looking to transition to Typescript. // I have tried to simplify the setup as much as possible Here is my tsconfig.json located in the root directory: { "compilerOp ...

Tips for expanding the functionality of the d3-selection module using TypeScript

I am currently working on a project that involves TypeScript and d3. I have already installed 'd3' and '@types/d3', and my use of d3 looks like this: import * as d3 from 'd3'; const x = d3.scaleLinear ... Everything was goin ...

Adjusting the size of a Video/Image Slider to perfectly fit the screen dimensions (both width and height

I have been using a slider code to display my images and videos. The code can be found here: Code:https://codepen.io/1wdtv/pen/jbjZeb The issue I am facing is that the slider is only responsive in terms of width. This means that when resizing the browser ...

Leveraging a function for filtering in AngularJS

I have developed an application where the content filter changes depending on which button is clicked. I have managed to figure out the straightforward filters, but now I am attempting to create a filter that displays content within a specified range. Bel ...

Invalid Syntax: The token '21' is found unexpectedly at column 12 in the expression [2013-08-28 21:10:14] beginning at [21:10:14]

I'm in the process of creating a straightforward directive for a date countdown. However, I've hit a roadblock with this particular error: Syntax Error: Token '21' is an unexpected token at column 12 of the expression [2013-08-28 21:10 ...

TypeScript introduces a flexible generic type, Optional<T, Props>, allowing customized props for a specific

In my attempt to develop a type called Optional<T, TProps>, where T represents the initial type and TProps is a union type of properties that need to be optional. As an illustration: type A = Optional<{a: string, b: string}, 'a'&g ...

What exactly does the term "new.target" refer to?

The ECMAScript 2015 specification references the term new.target a total of three times - once in section 14.2.3: Although Contains typically does not analyze most function forms, it is specifically used to identify new.target, this, and super usage wit ...

The input text in the Typeahead field does not reset even after calling this.setState

As I work on creating a watchlist with typeahead functionality to suggest options as the user types, I encountered an issue where the text box is not resetting after submission. I attempted the solution mentioned in this resource by calling this.setState( ...

Enhance your TypeScript code using decorators with inheritance

Exploring the realm of Typescript decorators has led me to discover their intriguing behavior when combined with class inheritance. Consider the following scenario: class A { @f() propA; } class B extends A { @f() propB; } class C exten ...

Exploring the capabilities of using Watir-webdriver with JavaScript and SignalR polling in Firefox

I am currently dealing with a JavaScript-focused website that utilizes SignalR polling. This has been causing Watir-Webdriver to time out during page loading. I have made some progress by adding the following command: driver.execute_script '$.conne ...

"An error occurred while trying to resolve "npm" from npm.fontawesome.com

Within my Angular project, I am utilizing a module from When I run the following command: npm --loglevel info install grun locally, it finishes without any issues. However, when I run this command on the build server, an error occurs. In my .npmrc file: ...

Using Jquery to hide or show objects within a <div> when clicked

My goal is to create a webpage that displays three different contents based on which button is clicked. Below is the code for reference: I want the page to show three specific sections: A search bar only when the 'search' button is clicked, T ...

React Redux not properly handling text input updates when onChange event is triggered

I have come across similar inquiries, but they haven't provided the solution I need. Currently, I am working on a React project where I am integrating redux. This is how my index.js looks: import React from "react"; import ReactDOM from "react-dom"; ...

Dynamic property Key in TypeScript

Imagine receiving data from a search engine in the following format: const resultDe = { details_de: "Ein paar Informationen", foo_de:{bar:"barDe"}, code: "1C60" } const resultEn = { details_en: "Some information", fo ...

I encountered the following error: Failed to parse due to the module '@babel/preset-react' being missing

Encountering a parsing error: Module '@babel/preset-react' cannot be found. Upon creating schema.js, tweetSchema.js, userSchema.js, issues arose with import, export, and export from all three files showing red lines. schema.js: import createSche ...

Error encountered when attempting to import Angular Version 9.1.4: TS2314 error code

I recently created a custom Angular library using version 9.0.7 of Angular. This library was successfully imported into applications running the same version without any issues. However, when attempting to import this library into an Angular app running ve ...

Transfer a table row between tables - AngularJS

I am seeking guidance on how to implement ng-repeat in order to transfer data from one table to another. Essentially, I have a "master" table that displays data fetched from an API request. Each row in this table has a button labeled "favorite-this-row". W ...

Add distinctive formatting for the final element that is not the last child

Presented with a fascinating challenge, I find myself with an ever-changing number of .child.red children. I am in need of referencing the last .child.red element dynamically using styles. Although I have attempted to achieve this on my own, I am curious a ...

The Strong Password checker fails to identify the presence of a forward slash

Here is a regex I have for validating a strong password: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d!$\/%@]{6,20}$/ Criteria: Alphanumeric with special characters $/%@ At least 1 number At least 1 lowercase letter At least ...

Tutorial on how to update a specific value in an array of objects using setState on click event

I need to toggle the active class on click, setting it to a local state and changing all other objects in the state to inactive. const [jobType, setJobType] = useState([ { "class": "active", "type& ...