Issue with button functionality in Angular 5

I followed a tutorial on YouTube that I came across here but I'm facing an issue with the Edit button not populating the fields on the left. Here are the relevant code snippets:

employee-list.component.html

    <h6 class="text-center">Employee Register</h6><br>
    <table class="table table-sm table-hover">
    <tr *ngFor="let employee of employeeList">
        <td>{{employee.name}}</td>
        <td>{{employee.position}}</td>
        <td>
            <a class="btn" (click)="onEdit(employee)">
                <i class="fa fa-pencil-square-o"></i>
            </a>
            <a class="btn" (click)="onDelete(employee.$key)">
                <i class="fa fa-trash-o"></i>
            </a>
        </td>
    </tr>
</table>

employee-list.component.ts

    onEdit(emp : Employee){
        this.employeeService.selectedEmployee = Object.assign({}, emp);
  }

employee.service.ts

import { Injectable } from '@angular/core';
import { AngularFireDatabase, AngularFireList } from 'angularfire2/database';
import { Employee } from './employee.model';

@Injectable()
export class EmployeeService {

    employeeList : AngularFireList<any>;
    selectedEmployee : Employee = new Employee();

  constructor(private firebase : AngularFireDatabase) { }
    getData(){
        this.employeeList = this.firebase.list('employees');
        return this.employeeList;
    }

    insertEmployee(employee : Employee){
        this.employeeList.push({
            name: employee.name,
            position: employee.position,
            office: employee.office,
            salary: employee.salary
        });
    }

    updateEmployee(employee : Employee){
        this.employeeList.update(employee.$key, 
            {
            name: employee.name,
            position: employee.position,
            office: employee.office,
            salary: employee.salary
        });
    }

    deleteEmployee($key : string){
        this.employeeList.remove($key);
    }
}

It seems like the onEdit() method is being called but it's not filling in the fields as expected. Any assistance on this matter would be highly appreciated.

employee.component.html

    <form #employeeForm="ngForm" (ngSubmit)="onSubmit(employeeForm)">
    <input type="hidden" name="$key" #$key="ngModel" [(ngModel)]="employeeService.selectedEmployee.$key">
    <div class="form-group">
        <label>Name</label>
        <input class="form-control" name="name" #name="ngModel" [(ngModel)]="employeeService.name" placeholder="Full Name" required>
    </div>
    <div class="form-group">
        <label>Position</label>
        <input class="form-control" name="position" #name="ngModel" [(ngModel)]="employeeService.position" placeholder="Position">
    </div>
    <div class="form-group">
        <label>Office</label>
        <input class="form-control" name="office" #name="ngModel" [(ngModel)]="employeeService.office" placeholder="Office">
    </div>
    <div class="form-group">
        <label>Salary</label>
        <div class="input-group">
            <div class="input-group-addon">
                <i class="fa fa-dollar"></i>
            </div>
        <input class="form-control" name="salary" #name="ngModel" [(ngModel)]="employeeService.salary" placeholder="Salary">
    </div>
    </div>
    <div class="form-group">
        <button class="btn btn-default" type="submit" [disabled]="!employeeForm.valid">
            <i class="fa fa-floppy-o"></i>
            Submit</button>
        <button class="btn btn-default" type="button" (click)="resetForm(employeeForm)">
            <i class="fa fa-repeat"></i>
            Reset</button>
    </div>
</form>

employee.component.ts

import { Component, OnInit } from '@angular/core';
import { NgForm } from '@angular/forms';
import { EmployeeService } from '../shared/employee.service';
import { ToastrService } from 'ngx-toastr';

@Component({
  selector: 'app-employee',
  templateUrl: './employee.component.html',
  styleUrls: ['./employee.component.css']
})
export class EmployeeComponent implements OnInit {

  constructor(private employeeService : EmployeeService, private tostr : ToastrService) { }

  ngOnInit() {
    this.resetForm();
  }

  onSubmit(employeeForm : NgForm){
    if(employeeForm.value.$key == null)
        this.employeeService.insertEmployee(employeeForm.value);
    else
                this.employeeService.updateEmployee(employeeForm.value);

    this.resetForm(employeeForm);
    this.tostr.success('Submitted Successfully', 'Employee Register');
  }

  resetForm(employeeForm? : NgForm){
    if(employeeForm != null)
        employeeForm.reset();
    this.employeeService.selectedEmployee = {
        $key : null,
        name : '',
        position : '',
        office : '',
        salary : 0
    }
  }
}

Answer №1

The issue seems to be located in the employee.component.html file. It appears that you are trying to bind the form model with data from your service using

[(ngModel)]="employeeService.name"
. However, the employeeService does not have a property or method called name, resulting in an undefined value being returned. To correctly populate the form with the selected employee's name, you should use
employeeService.selectedEmployee.name
.

A revised solution could look like this:

<div class="form-group">
  <label>Name</label>
  <input class="form-control" name="name" #name="ngModel" [(ngModel)]="employeeService.selectedEmployee.name" placeholder="Full Name" required>
</div>
...

Additional Note

You may want to check the access modifier for employeeService in employee.component.ts. If it is marked as private, accessing it in the template might cause issues. Consider changing it to public to resolve any potential problems. Understand the difference between these access modifiers for better code organization and maintenance.

Answer №2

To enhance your EmployeeService, consider updating it as shown below and including additional getter and setter methods.

@Injectable()
export class EmployeeService {

    employeeList : AngularFireList<any>;
    _selectedEmployee : Employee = new Employee();

    constructor(private firebase : AngularFireDatabase) { }

    //Include the following getter and setter methods

    get selectedEmployee():Employee{
        return this._selectedEmployee ;
    }

    set selectedEmployee(emp:Employee) {
        this._selectedEmployee = emp;
    }

......
    ......
.....
}

If you are encountering issues with setting or updating the selected employee in your onEdit function, utilizing the getter/setter provided above should resolve the issue.

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

Tips for verifying the presence of an active session after closing the browser

Here is my situation: When a user logs into the app and then opens another browser window, they are already authenticated thanks to express-session, bypassing the login page. This pattern continues for subsequent browser windows. The issue I am facing no ...

What is the method for dynamically selecting generics from a function in a union type using Typescript?

Suppose there is a function defined as follows: type FooParams<Params extends unknown[], Result> = { name: string, request: (...params: Params) => Promise<Result> } const foo = <Params extends unknown[], Result>(params: FooParams ...

Organize Radio Selectors

My intention was to align the radio buttons as shown in the image below: https://i.stack.imgur.com/oPTjD.jpg However, the final result looked like this https://i.stack.imgur.com/Mixga.jpg Below is the code for your reference HTML <div class="form ...

Leveraging the useRoute() function with Vue 3 Composition API and Typescript: [Vue alert]: The injection "Symbol(route location)" was not detected when employing Typescript

Just recently, I upgraded a Vue 2 application that heavily uses Vue Router and TypeScript to Vue 3. During the migration process, I switched a function from reading the route using this.$route in the Options API to using useRoute() in the Composition API. ...

Develop an encoding feature utilizing mustache templates

Exploring the world of mustache for the first time, I haven't been able to find the answer through my basic searching. I am attempting to create a template in Typescript for encoding an unknown number of fields. The structure will be something like th ...

Unable to get the onchange event to trigger for a span element

Is there a way to trigger the onchange event on a span element that doesn't seem to be working? Here is the code I am using: Attempt 1 document.getElementById(seconds).addEventListener('change', (event: MutationEvent & { path: any }) =& ...

Error in executing a function within an asynchronous function sequence

Whenever a user logs in, I want to update their data in Firestore. However, the code I am using does not seem to work as expected. It fails to create a custom User object from the firebase.User. Can anyone help me understand why this is happening and how ...

The static folder does not load as expected in Express

I'm facing challenges with a Node application that I am developing. Here is the folder structure of the app: controllers // contains controllers helpers // contains helper functions config // includes configuration files public // holds a compiled ...

Adjusting the information of a fresh element within an array will subsequently impact all other elements within

I have a problem with my Angular application where I need to add new elements to an array. The array is shown on the GUI after clicking a button. Here is how my current array looks: [ {name: 'user1', percentage: '1'} ] But after click ...

Steps to integrate an Angular library from Github to another Angular project without the need to publish the library to NPM

TL;DR - Looking for a solution that allows direct installation of Angular Library into Angular application without NPM or NPM symlink I've set up two demo repositories on Github, one for the Angular Library and one for an Angular application that wil ...

Tips for customizing the appearance of a specific mat-button component in an Angular project

In my Angular application, I have set up a scenario where users are presented with multiple choices through buttons. When a user clicks on a button, a specific component is displayed based on their choice. I am currently working on enhancing the styling of ...

ngx-bootstrap, Component Modal: There were no elements found that matched the selector "modal-content"

My application uses Angular 7 with "ngx-bootstrap": "^3.1.4" and "bootstrap": "^4.3.1". Is it possible that these versions are compatible? I am attempting to open a component in a modal following this query: ngx-bootstrap How to open a modal from another ...

Swapping the position of the toggle and label elements in Angular 8 with Bootstrap 4

Hey there, I am currently working with Angular8 and Bootstrap 4. On one of my screens, I have implemented checkboxes but facing an issue where the checkbox appears before the label. Is there a way to switch this order so that the label comes first? Any hel ...

Animating Page Transitions within Ionic 2

In my Ionic 3 application, I have a basic tabs template where I switch between tabs by swiping left or right. Everything works perfectly except there is no animation effect when transitioning between tabs either by tapping or swiping. I am able to achieve ...

Storing data from a collection of interface objects in a string array

Take a look at the following code snippet: import React, {FC} from 'react'; import {useFetchErrors} from "../Api/Api"; import {useLocation} from "react-router-dom"; interface ExecutionTableProps { project_id: number } const ...

Error encountered in EBS Node.js 14: TS5033 - Unable to save file due to EACCES error related to permission denial

Upon creating a new EBS environment with Node.js 14 to replace the deprecated old one, I encountered the following error: Jul 27 22:34:53 ip-172-31-42-207 web: error TS5033: Could not write file '/var/app/current/build/server/validation.js.map': ...

Cypress is unable to drag a customized angular cdkDragHandle functionality

My mind is unraveling due to this issue. I have a drag and drop list in my application with a customized drag handle, but Cypress seems incapable of dragging it. When manually dragged by the user, everything works flawlessly. Below is the simple component ...

TypeScript: The RegExp element is inferred to have an 'any' type by default

Looking to develop a function that can handle duration strings like 12ms, 7.5 MIN, or 400H, and then convert them into milliseconds. const units = { MS: 1, S: 1 * 1000, MIN: 60 * 1 * 1000, H: 60 * 60 * 1 * 1000 } export function toMS(str: strin ...

component is receiving an incompatible argument in its props

I am facing a situation where I have a component that works with a list of items, each with an ID, and a filtering function. The generic type for the items includes an ID property that all items share. Specific types of items may have additional properti ...

Staying patient while the array loads data from Firebase so that methods can be called efficiently

As an Angular newbie, I am working on a project that involves accessing data from Firebase using an Angular service. My goal is to retrieve this data, store it in an array, and then perform some operations on that array. However, due to my limited experien ...