blackHawk
blackHawk

Reputation: 6307

Angular2 : No provider for String! (child -> String) in [Array in parent

Im building basic Todo App in angular2 when I click add button to send data from parent to child using input I get No provider for string! (child->string), and no data displayed only button at the child class is shown, what does it mean

here is parent component:

@Component({
selector : 'parent-component',
directives : [child],
template : `
<h1 class= "text-center">ToDo App</h1>
<div class = "form-group">
<lable>Task</lable>
<input type = "text" class = "form-control" #task>
<lable>Detail</lable>
<input type = "text" class = "form-control" #detail >
<button type = "submit" class  = "btn btn-default" 
(click) = "addtask(task,    detail)">Add Task</button>


<child-component *ngFor = "#todo of Array" [taskobject] = "todo">
Loading... </child-component>
</div>

`
})
class parent{
//taskobj : {task : string, details : string, id:  number};
Array : child[];
id : number;

constructor(){

    //i want this to initialize asa parent create
    this.Array = [];
}

addtask(task : HTMLInputElement, detail : HTMLInputElement){
    // this.taskobj.task= task.value;
    // this.taskobj.details = detail.value;
   this.id = Date.now();
    // this.array.push();

    this.Array.push(new child(task.value, detail.value, this.id ));
    console.log(Array)
    task.value = '';
    detail.value = '';

}

And this is child component:

@Component({

selector : 'child-component',
inputs : ['taskobject'],
//outputs : ['objectsend'],
template : `
  {{taskobject.task}}
  {{taskobject.details}}
  <button type = "button" class = "btn btn-default" 
  (click) = "deletetask()">Delete</button>
  <button type = "button" class = "btn btn-defualt" 
  (click) = "updatetask()">Update</button>

  `
  })
class child{

//we are creating a instance just as configured as child component 
task : string;
detals : string;
id : number;
//array : any[];

constructor(task : string, detail : string, id : number){
    this.task = task;
    this.detals = detail;
    this.id = id;
}

}

Upvotes: 4

Views: 8325

Answers (2)

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

Reputation: 657248

Constructor parameters are resolved from DI providers specified in bootstrap(AppComponent, [SomeProvider, SomeOtherProvider, ...]);

Inputs are assigned automatically but only after the lifecycle call to ngOnInit().

@Component({
  selector : 'child-component',
  inputs : ['taskobject'],
  //outputs : ['objectsend'],
  template : `
    {{taskobject?.task}}
    <!-- use the safe-navigation operator ?. to avoid errors 
      when `taskobject` is not yet set
    -->
    {{taskobject?.details}}
    <button type = "button" class = "btn btn-default" 
    (click) = "deletetask()">Delete</button>
    <button type = "button" class = "btn btn-defualt" 
    (click) = "updatetask()">Update</button>
    `
})
class child {
  //we are creating a instance just as configured as child component 
  taskobject: any;
  task : string;
  detals : string;
  id : number;
  //array : any[];

  constructor() {
  }

  // when this callback is called the 
  // `taskobject` (from `inputs : ['taskobject'],`) 
  // is initialized 
  ngOnInit() {
    this.task = taskobject.task;
    this.detals = taskobject.detail;
    this.id = taskobject.id;
  }
}

Upvotes: 1

Thierry Templier
Thierry Templier

Reputation: 202156

You got an error since Angular2 instantiate the child class by its own and try to inject in it the parameters you define at its constructor level. There is no associated provider for them...

Otherwise if you want to reference children components from parent ones, you could leverage the @ViewChild decorator to reference the child component from the parent one by injection:

import { Component, ViewChild } from 'angular2/core';  

(...)

@Component({
  selector: 'my-app',
  template: `
    <h1>My First Angular 2 App</h1>
    <child></child>
    <button (click)="submit()">Submit</button>
  `,
  directives:[App]
})
export class AppComponent { 
  @ViewChild(SearchBar) searchBar:SearchBar;

  (...)

  someOtherMethod() {
    this.searchBar.someMethod();
  }
}

Here is the updated plunkr: http://plnkr.co/edit/mrVK2j3hJQ04n8vlXLXt?p=preview.

You can notice that the @Query parameter decorator could also be used:

export class AppComponent { 
  constructor(@Query(SearchBar) children:QueryList<SearchBar>) {
    this.childcmp = children.first();
  }

  (...)
}

Hope it helps you, Thierry

Upvotes: 3

Related Questions