FeroX
FeroX

Reputation: 57

Pass an object between Components with service

I read in several pages that the best way to pass an object between components, when doing the routing, is the use of a service.

I have relied on this last example (http://plnkr.co/edit/NpLKAgY3FkzhOK9eBeIb?p=preview) and I made the following code that gives me problems:

Service:

@Injectable()
export class tableService {

    public category: Category;
}

Component 1:

export class tableComponent {
    categorys: Category[] = []; 
    category: Category;

passItemCat(event: any) {
    this.category = {
        Code: "09",
        Attachments: [],
        Description: "eee",
        Response: {
            Destination: "",
            HtmlText: "",
            Text: "",
            Type: "",
        },
        Taxonomy: "ddd",
     }
    event.preventDefault(); 
}


constructor(public _tableService: tableService) { }

ngOnInit(): void {
    //get API for categorys
}

ngOnDestroy() {
    this._tableService.category = this.category;
}
}

Template Componente 1

<tr *ngFor="let item of categorys">
            <td>
                <nav>
                    <button routerLink="/ModifyCategory" routerLinkActive="active" class="btn btn-warning" (click)="passItemCat($event)">Modify</button>
                </nav>
            </td>

Componente 2

export class modifyCategoryComponent{
    category: Category;

    constructor(public _tableService: tableService) { }

    ngOnInit() {
        this.category = this._tableService.category;
    }
}

The problem occurs in the OnInit of the component 2, which does not find elements in this._tableService.category.

PS. In this step (I proceed in small steps to learn) use a static category on click, subsequently I want to read the item of the component template 1. if you want to suggest some improvements are all ears.

Upvotes: 1

Views: 1203

Answers (1)

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 658037

That's probably because modifyCategoryComponent reads _tableservice.category before tableComponent set _tableService.category.

If you instead use an Observable then the receiving component gets notified when a value is set or updated.

@Injectable()
export class tableService {
  private category:BehaviorSubject<Category> = new BehaviorSubject<Category>(null);
  get $category() {
    return this.category.asObservable();
  }
  setCategory(value:Category) {
    this.category.next(value);
  }
}

Set a new category

ngOnDestroy() {
  this._tableService.setCategory(this.category);
}

Subscribe to category changes

ngOnInit() {
    this._tableService.$category.subscribe(value => this._tableService.category = value);
}

See also https://angular.io/docs/ts/latest/cookbook/component-communication.html

Upvotes: 2

Related Questions