1

How to use / manipulate @Input()items in child-component.ts before we pass it to child-component.html? I'm getting empty object if console log in ngOnInit

child-component.ts

  @Input()items: any[] = [];

parent.component.html

<child-component [items]="items"></child-component>

parent.component.ts

  indexOrders() {
    this.orderService
      .indexOrders()
      .subscribe(
        (res) => {
        this.items = res;
        },
        (err) => {
          serviceHttpErrorHandler(err);
        },
      );
  }

sample.json

sample response that passed to this.item

[
   {
      "text":"wood",
      "value":"100"
   },
   {
      "text":"chair",
      "value":"200"
   },
   {
      "text":"board",
      "value":"300"
   }
]
SKL
  • 1,243
  • 4
  • 32
  • 53

2 Answers2

3

You can also use @Input() on setter methods and not just class member variables. You add @Input() to a method, modify the values and then assign it to a member variable.

child.component.ts

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

  
  _items: any;

  constructor() { }

  ngOnInit() {
  }

  @Input()
  public set items(items:any) 
  {
    // YOU CAN MODIFY THE ITEMS HERE
    // BEFORE ASSIGNING TO _items

    this._items = items;
  }

}

Below are a stackblitz example along with the angular documentation.

https://stackblitz.com/edit/angular-rqqn2j

https://angular.io/guide/component-interaction#intercept-input-property-changes-with-a-setter

Community
  • 1
  • 1
Jason White
  • 5,495
  • 1
  • 21
  • 30
  • Why people rather do this than doing the modification using the .pipe of RxJS? that way when the subscription happens the data is how you want it. – Patricio Vargas Aug 31 '19 at 01:06
  • @PatricioVargas Using the example of order items, maybe you want to generate a total or subtotals before displaying the data in the child component. You could receive the data through `@Input()` and do the calculations. If you're just modifying the data structurally then the `pipe` may be a better option. – Jason White Aug 31 '19 at 01:12
  • You can achieve returning a total of subtotals still with ```pipe()``` RxJS has ```map()```, ```reduce()``` etc that can help you accomplish that. – Patricio Vargas Aug 31 '19 at 01:14
2
   //Create and Observable
   $items: Observable<any>;

   indexOrders() {
         this.$items= this.orderService
          .indexOrders()
          .pipe(
             //do whatever you want to do here to modify the data,
             catchError(error)
          );
      }

HTML

   <child-component [items]="$items | async"></child-component>

The async pipe will do the subcription and unsubscription for you. That way you don't have to destroy the subscription if you use .subscribe()

https://blog.angularindepth.com/reading-the-rxjs-6-sources-map-and-pipe-94d51fec71c2

https://www.learnrxjs.io/operators/error_handling/catch.html

Take a look to the async pipe and the pipe from RxJS. People use them all the time in the real world. Angular is all about reactive programming.

Patricio Vargas
  • 5,236
  • 11
  • 49
  • 100