bassxzero
bassxzero

Reputation: 5041

Angular 2 router class instance

Sorry in advance. I'm new to Angular so I'm sure i just don't know enough vocab to google the correct thing. I'm trying to make a simple CRUD app but my edit functionality is not working.

Problem

  1. No matter what row i click from my dashboard, when the edit view shows it always has the same values in the form inputs. When I log the routerParam in edit.component.ts -> ngOnInit() it always has the same value, but my dashboard.component.html template looks like it should provide the correct parameter to the gotoEdit method. Am I doing something wrong with my binding?

  2. In edit.component.ts -> ngOnInit() I'm getting the error message Type 'string' is not assignable to type 'Row'. I have tried casting the email routeParam to a Row and creating a new Row instance with the values from temp, but both failed.

Ideally I would like bypass the gotoEdit method and have the DashboardComponent pass the row to the EditComponent's email property, but I have no idea how to.

Router Config

@RouteConfig([
  { path: '/dashboard',  name: 'Dashboard',  component: DashboardComponent ,  useAsDefault: true },
  { path: '/insert',  name: 'Insert',  component: InsertComponent },
  { path: '/edit/:email',  name: 'Edit',  component: EditComponent }
])

Row Class

export class Row {
    PK: number;
    BudgetCenter: string;
    EmailAddress: string;
}

Dashboard.component.html

<p>All Emails</p>
<table class="table table-condensed table-hover">
    <thead>
        <tr>
            <th>ID</th>
            <th>Budget Center</th>
            <th>Email Address</th>
            <th><a (click)="gotoAdd()" ><span class="glyphicon glyphicon-plus"></span></a></th>
        </tr>
    </thead>
    <tbody>
        <tr *ngFor="let email of emails">
            <td>{{email.PK}}</td>
            <td>{{email.BudgetCenter}}</td>
            <td>{{email.EmailAddress}}</td>
            <td>
                <a (click)="gotoEdit(email)"  ><span class="glyphicon glyphicon-pencil"></span></a>
                <a (click)="deleteRow(email)" ><span class="glyphicon glyphicon-trash"></span></a>
            </td>
        </tr>
    </tbody>
</table>

dashboard.component.ts

import { Component, OnInit } from '@angular/core';
import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/router-deprecated';
import { Router } from '@angular/router-deprecated';
import { EmailService }  from './email.service';
import { Row } from './row';

@Component({
  selector: 'my-dashboard',
  templateUrl: 'app/dashboard.component.html',
  directives: [ROUTER_DIRECTIVES]
})
export class DashboardComponent implements OnInit {
  emails: Row[] = [];

  constructor (
      private emailService: EmailService,
      private router: Router ) {
  }

  gotoAdd()
  {
    this.router.navigate(['Insert']);
  }

  gotoEdit(row: Row)
  {    
    //this.router.navigate(['Edit', row]);
    console.log('in gotoEdit()');
    this.router.navigate(['Edit', {email: row}]);
  }

  deleteRow(row: Row)
  {
    let index: number = this.emails.indexOf(row, 0);
    if (index > -1) {
      //console.log('found it', index);
      this.emailService.deleteRow(row);
      this.emails.splice(index,1);
    }
  }

  ngOnInit() {
    this.emailService.get().then(emails => this.emails = emails);
  }

}

edit.component.html

<form *ngIf="email" class="form-horizontal">
    <div class="form-group">
        <label for="inputBudgetCenter" class="col-sm-2 control-label">Budget Center</label>
        <div class="col-sm-10">
            <input [(ngModel)]="email.BudgetCenter" type="text" class="form-control" id="inputBudgetCenter" placeholder="Example: B001">
        </div>
    </div>
    <div class="form-group">
        <label for="inputEmail" class="col-sm-2 control-label">Email</label>
        <div class="col-sm-10">
            <input [(ngModel)]="email.EmailAddress" type="text" class="form-control" id="inputEmail" placeholder="Example: [email protected]">
        </div>
    </div>
    <div class="form-group">
        <div class="col-sm-offset-2 col-sm-10">
            <button (click)="updateRow()" type="submit" class="btn btn-default">Save</button>
        </div>
    </div>
</form>

edit.component.ts

import { Component, OnInit, Input } from '@angular/core';
import { Router } from '@angular/router-deprecated';
import { RouteParams } from '@angular/router-deprecated';
import { EmailService }  from './email.service';
import { Row } from './row';

@Component({
    selector: 'edit-row',
    templateUrl: 'app/edit.component.html',
    inputs: ['email']
})
export class EditComponent implements OnInit {
   @Input() email: Row;

    constructor (
        private emailService: EmailService,
        private router: Router,
        private routeParams: RouteParams) {
    }

    updateRow()
    {
        console.log('in update', this.email);
        /*this.emailService
            .addRow(this.budgetCenter, this.emailAddress)
            .then( ()=> {
                this.router.navigate(['Dashboard']);
            } );*/
    }

    ngOnInit() {
        console.log('in edit',this.routeParams.get('email'));
        let temp: Row = this.routeParams.get('email');
        this.email = temp;
        //this.email.BudgetCenter = temp.BudgetCenter;
        //this.email.EmailAddress = temp.EmailAddress;
        //this.emailAddress = temp.;
        //this.budgetCenter = temp.;
        /*   console.log('in edit component init', this.email);
        let temp = JSON.parse(this.routeParams.get('email'));
        console.log('temp', temp);
        this.email = new Row(temp.PK, temp.BudgetCenter, temp.EmailAddress);
        */
    }
}

Upvotes: 1

Views: 481

Answers (1)

Doron Brikman
Doron Brikman

Reputation: 2584

You should only pass the id of the current email through the router, and then get it from your EmailService by that id. like maxisam suggests you can use the new router and then you will get the changes of the route inside EditComponent as an Observable.

something like this:

ngOnInit() {
    this.sub = this.route
      .params
      .subscribe(params => {
        const id = +params['id'];
        this.emailService.get(id)
          .then(email => {
            this.email = email;
          });
      });
  }

Upvotes: 1

Related Questions