What is the best way to dynamically populate a list in Angular when a button is clicked?

Currently, I'm in the process of developing a website that will serve as the interface to control a robot. My goal is to create a user-friendly system where users can input latitude and longitude coordinates, click a designated button, and have those coordinates automatically added to an Angular list element.

https://i.sstatic.net/rwPnc.png

The website layout includes two input fields for latitude and longitude respectively, along with a button for adding waypoints. Upon entering the desired coordinates and clicking 'Add Waypoint', the information is expected to populate the list element in real-time.

Below is an excerpt of the HTML code I've implemented:

<mat-grid-list cols="8" rowHeight="350px">
<mat-grid-tile style="background-color: royalblue;" colspan="2">
    <mat-card>
        <mat-card-title>Rotation Data</mat-card-title>
        <mat-card-actions>
            <mat-slider class="slider" [(ngModel)]="sliderVal1"></mat-slider>
            <mat-progress-bar
              class="example-margin"
              [color]="color"
              [mode]="mode"
              [value]="sliderVal1"
              [bufferValue]="sliderVal1">
            </mat-progress-bar>
            <p>Pitch: {{sliderVal1}}</p>
    
            <mat-slider class="slider" [(ngModel)]="sliderVal2"></mat-slider>
            <mat-progress-bar
              class="example-margin"
              [color]="color"
              [mode]="mode"
              [value]="sliderVal2"
              [bufferValue]="sliderVal2">
            </mat-progress-bar>
            <p>Roll: {{sliderVal2}}</p>
        </mat-card-actions>
    </mat-card>
</mat-grid-tile>

<mat-grid-tile style="background-color: royalblue;"  colspan="2">
    <mat-card>
        <mat-card-title>Driving Controls</mat-card-title>
        <mat-card-actions>
            <p>Speed: {{sliderVal3}}</p>
            <mat-slider class="slider" [(ngModel)]="sliderVal3"></mat-slider>
    
            <mat-divider></mat-divider>
            <p>Turning: {{sliderVal4}}</p>
            <mat-slider class="slider" [(ngModel)]="sliderVal4"></mat-slider>
    
            <mat-divider></mat-divider>
            <p>Configuration Mode: 0</p>
            <button mat-button [matMenuTriggerFor]="menu">Default Driving</button>
            <mat-menu #menu="matMenu">
                <button mat-menu-item>1</button>
                <button mat-menu-item>2</button>
            </mat-menu>
    
            <div class="reset-button">
                <button mat-button color="primary" (click)="resetControls()">Reset Controls</button>
            </div>
        </mat-card-actions>
    </mat-card>
</mat-grid-tile>

<mat-grid-tile style="background-color: royalblue;" colspan="4">
    <mat-card class="colspan-4">
        <mat-card-title>Waypoints</mat-card-title>
        <mat-card-actions>
            <mat-grid-list cols="3" rowHeight="85px">
                <mat-grid-tile>
                    <mat-form-field class="example-form-field" appearance="fill">
                        <mat-label>Latitude</mat-label>
                        <input matInput type="text" [(ngModel)]="latValue">
                        <button *ngIf="latValue" matSuffix mat-icon-button aria-label="Clear" (click)="latValue=''">
                          <mat-icon>close</mat-icon>
                        </button>
                    </mat-form-field>     
                </mat-grid-tile>
                <mat-grid-tile>
                    <mat-form-field class="example-form-field" appearance="fill">
                        <mat-label>Longitude</mat-label>
                        <input matInput type="text" [(ngModel)]="lonValue">
                        <button *ngIf="lonValue" matSuffix mat-icon-button aria-label="Clear" (click)="lonValue=''">
                          <mat-icon>close</mat-icon>
                        </button>
                    </mat-form-field>                          
                </mat-grid-tile>
                <mat-grid-tile>
                    <button mat-button color="primary">Add Waypoint</button>
                </mat-grid-tile>
                <mat-grid-tile>
                    <mat-list>
                        <div mat-subheader>Waypoints</div>
                        <mat-list-item>
                            <mat-icon mat-list-icon>place</mat-icon>
                            <div mat-line>Waypoint 1</div>
                            <div mat-line>{{latValue}}, {{lonValue}}</div>
                        </mat-list-item>
                    </mat-list>
                </mat-grid-tile>
            </mat-grid-list>
        </mat-card-actions>
    </mat-card>
</mat-grid-tile>

Answer №1

Create an array called waypoints and a function to add waypoints in your component.ts file:

  waypoints: {lat: number, lon: number}[] = [];

  addWaypoint() {
    this.waypoints.push({lat: this.latValue, lon: this.lonValue});
  }

Add a click event to your button:

<button (click)="addWaypoint()">Add Waypoint</button>

Display your waypoints using *ngFor:

<div *ngFor="let waypoint of waypoints">
    <div>{{waypoint.lat}}, {{waypoint.lon}}</div>
</div>

In this example, a div element is used, but you can apply *ngFor to any element (such as mat-list-item).

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

Deciding between bundling a Typescript package and using tsc: When is each approach the best choice

When it comes to publishing a Typescript NPM package (library, not client), I have two main options: 1. Leveraging Typescript's compiler First option is to use the Typescript compiler: tsc and configure a tsconfig.json file with an outDir setting: { ...

Is there a possibility of Typescript expressions `A` existing where the concept of truthiness is not the same as when applying `!!A`?

When working with JavaScript, it is important to note that almost all expressions have a "truthiness" value. This means that if you use an expression in a statement that expects a boolean, it will be evaluated as a boolean equivalent. For example: let a = ...

I am seeking advice on how to create an extension for a generic class in TypeScript specifically as a getter

Recently, I discovered how to create extensions in TypeScript: interface Array<T> { lastIndex(): number } Array.prototype.lastIndex = function (): number { return this.length - 1 } Now, I want to figure out how to make a getter from it. For exam ...

various issues with fonts and Uncaught Eval error

I've been encountering multiple font/style errors and an uncaught eval. I have attached a picture for reference. My Angular application is not functioning properly, and I suspect these errors may be the reason. However, I am unsure of their significan ...

typescript Object that consists of properties from an array with a defined data type

I have an array consisting of strings. I am trying to transform this array into an object where each string is a property with specific attributes assigned to them. export interface SomeNumbers { name: string; value: number; } const arr = ['apple& ...

Utilizing MSAL's loginRedirect within an Ngrx Effect: A step-by-step guide

Is there a way to utilize Msal angular's loginRedirect(): void function instead of loginPopup(): Promise in an Ngrx Effect? I've been able to successfully implement the loginPopup() method, but since loginRedirect() has a void return type, it di ...

I have set up a custom ag-grid three times within a single component, however, only the first instance is properly initialized while the other two instances are not initialized

I have developed a custom ag-grid for reusability in my project. Initially, when I initialize the custom ag-grid in one component, it works perfectly as shown below: example.html <html> <body> <input type="text"> <md-app-aggrid [c ...

Retrieve the thousand separator for numbers using Angular in various languages

When using the English locale, numbers appear as follows: 111,111,222.00, with a comma as the thousand separator and a point as the decimal separator. In languages like German, the same number would be represented as 111.111.222,00, reversing the positions ...

Updating a property in a JavaScript object using Angular

Working with Angular, I have a dataset: export class AppComponent { data = [ { "area1": { "format": "changethis" } ] I am looking to develop a function that can alter the value of a specific key. For e ...

The 'api' property is not found within the 'MyService' type declaration

Currently, I am working on a tutorial where we are building an Angular service to send emails from a form using the Mailthis Email API. In the code for the service, I encountered an error related to the 'api' variable that states "Property ' ...

The attribute 'map' is not found on the object of type 'List'

I am currently working on a project that involves lists, each with its own title. However, while using Map, I encountered the following error: Property 'map' does not exist on type 'List' Any suggestions on how to resolve this issue? ...

Is it possible to create a class object with properties directly from the constructor, without needing to cast a custom constructor signature

class __Constants__ { [key: string]: string; constructor(values: string[]) { values.forEach((key) => { this[key] = key; }); } } const Constants = __Constants__ as { new <T extends readonly string[]>(values: T): { [k in T[num ...

Managing non-mandatory information in a structured domain representation: What's the best approach?

When working on applications or domain models, I often ponder the most effective approach to handling incomplete or optional data. Typed languages like TypeScript and C# offer the advantage of defining models with strict types. While this can be beneficial ...

TS - The 'new' keyword can only be used with a void function

I'm encountering a strange TypeScript error: "Only a void function can be called with the 'new' keyword." What in the world? https://i.sstatic.net/bKAUT.png The constructor function looks like this: function Suman(obj: ISumanInputs): ...

Implementing TypeScript module resolution with Cucumber-js can be a bit tricky

Currently, I am in the process of creating a Proof of Concept for Cucumber-js using TypeScript. Everything is going smoothly except for one issue - I am facing difficulties when it comes to configuring the module resolution while utilizing tsconfig-paths. ...

Leveraging react-share in combination with react-image-lightbox

I have recently inherited a React project and am struggling to integrate react-share with react-image-lightbox. My experience with both React and Typescript is limited, so any assistance would be greatly appreciated. Below are the relevant code snippets: ...

Can a constant value be dynamically defined in Typescript?

Trying to dynamically define a constant in Typescript has proven to be more challenging than I anticipated. Here's what I attempted: define(name: string, value: any): boolean { var undef; const name = value; return name == undef; } ...

Exploring the data connections in Firebase Realtime Database using angularfire2

I am in need of querying comments and only requesting users that are listed in the comment by their userId. This is the structure of my database in Firebase realtime db: { "comments" : { "c_id1" : { "commentId" : "c_id1", "commentText" ...

Having trouble with accessing properties like `d3.svg()`, `d3.scale()` and other features of d3js within an Angular 2 environment

Struggling to incorporate d3.js into angular2. Below is the command I used to install d3 in Angular2: npm install --save d3 install --save-dev @types/d3 This is how my package.json appears: { "name": "my-app", "version": "0.0.0", "license": "M ...

What is the process for including an "everything" alternative on a dropdown menu?

Need assistance with my dropdown component that filters a list based on 'state' data. Below is the HTML code for the dropdown: <section class="select-wrapper {{wrapperClass}}" [ngClass]="{'expanded': toggle}" (click)="toggleSelect($ ...