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"
   }
]

6
  • parent.component.html should be <child-component [items]="items"></child-component> with brackets around items attribute. Commented Aug 31, 2019 at 0:27
  • what errors are you getting? Commented Aug 31, 2019 at 0:30
  • @JasonWhite, actually it was with bracket in real app. sorry didn't notice when create this question. Do u know how to use items in child-component.ts file before pass to html? Commented Aug 31, 2019 at 0:31
  • @JasonWhite, No error but Im getting empty object Commented Aug 31, 2019 at 0:33
  • Do you mean you want to modify the items in the child component before they're rendered in the template? Commented Aug 31, 2019 at 0:35

2 Answers 2

4

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

Sign up to request clarification or add additional context in comments.

3 Comments

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.
@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.
You can achieve returning a total of subtotals still with pipe() RxJS has map(), reduce() etc that can help you accomplish that.
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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.