1

I am trying to pass values from one component to other components, so far i have refereed some tuts and created my code but still facing issue.

I have following code in my SelectComponent.ts

    export class SelectComponent implements OnInit {
 user: LoginUser
 selectLicences = [
  { name: 'Control', id: 1, isChecked: false, quantity: 1 },
  { name: 'Complete', id: 2, isChecked: false, quantity: 1 },
 ]

ControlQuantity=10
CompleteQuantity=20

i want to access ControlQuantity and CompleteQuanitiy in my other "buyerComponent"

here is buyerComponent.ts

    export class BuyerComponent implements OnInit, OnDestroy,AfterViewInit {​
@ViewChild('selectProducts', {​ read: SelectComponent, static: false }​)
selectProducts: SelectComponent

CompleteQuantity:number
ControlQuantity:number
ngOnInit() {
    this.CompleteQuantity=this.selectProducts.CompleteQuantity
    this.ControlQuantity=this.selectProducts.ControlQuantitity
}
}

stackblitz link: https://stackblitz.com/edit/angular-ivy-umje3g?

18
  • What is selectProducts?, what is the relationship between the components?, Please refer this video you will get idea Commented Aug 23, 2021 at 5:39
  • i have added complete BuyerComponent Commented Aug 23, 2021 at 5:50
  • Please add HTML too. Commented Aug 23, 2021 at 5:54
  • Try using @Input on your child components. Avoid the use of @ViewChild as much as possible. It's not fit for unit-testing Commented Aug 23, 2021 at 5:55
  • 1
    Do not let your one component invadate and access internal matters of the other component. Better way, without services, would be to have a parent component which acts as a mediator. Component A emits an event which is listened and passed on to Component B. @ Input and @ output are your friends here. angular.io/guide/inputs-outputs Commented Aug 23, 2021 at 6:27

2 Answers 2

1

You can refer to the official documentation. https://angular.io/guide/inputs-outputs#sending-data-to-a-child-component

You can pass data to your child component via @Input() decorator.

export class buyerComponent implements OnInit{
    @Input() CompleteQuantity:number
    @Input() ControlQuantity:number
    
    ngOnInit() {
        this.CompleteQuantity=this.selectProducts.CompleteQuantity
        this.ControlQuantity=this.selectProducts.ControlQuantitity
    }
}

In your HTML page, you can pass data via the child component's selector tag.

Update: After seeing the code.

  • In AppModule, remove the BuyerComponent and Products components from Import and add them to the declaration array.

  • In Buyer.component.html the tag is incorrect. Correct tag is "app-products" instead of "app-select-products".

  • Add these as @Input() in the products component class

         @Input() CompleteQuantity:number
         @Input() ControlQuantity:number
    
  • Rename the existing Output() variables to another name in the products.component.ts class.

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

4 Comments

core.js.pre-build-optimizer.js:4002 ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'ControlQuantity' of undefined TypeError: Cannot read property 'ControlQuantity' of undefined at e.<anonymous> (buyer.component.ts:1418) at tslib.es6.js.pre-build-optimizer.js:100
@sonu2007 is it possible for you to share the code repo. It seems something is not right in your code. Either Github or Stackbliz would be great.
here you go stackblitz.com/edit/angular-ivy-umje3g?
@sonu2007 Many things are incorrect in the code. I have updated my answer based on that.
1

You have two alternatives:

  1. You can use a singleton service:
@Injectable({providedIn: 'root'})
export class SharedService {
  sharedValue = 1
}
@Component({…})
export class Component1 implements OnInit {
  public get prop(): number {
    return this.service.sharedValue;
  }
  constructor(private service: SharedService) { }
}
@Component({…})
export class Component2 implements OnInit {
  public get prop(): number {
    return this.service.sharedValue;
  }
  constructor(private service: SharedService) { }
}
  1. You have to use the parent component as a data-bridge

The parent (bridge component)

Note that the parent is not doing a lot of stuff but providing bindings between the shared data between children.

<div>
  <app-child1 
    [value]="value"
    (valueUpdated)="onChangeValueFromChildren($event)">
  </app-child1>
  <app-child2 
    [value]="value"
    (valueUpdated)="onChangeValueFromChildren($event)">
  </app-child2>
</div>
@Component({…})
export class ParentComponent implements OnInit {

  value = 2
  
  onChangeValueFromChildren(newValue: number) { 
    this.value = newValue
  }
}

Any of the children components

@Component({…})
export class Child1 implements OnInit {

  @Output valueUpdated = new EventEmitter<number>();
  
  onClick() { 
     this.valueUpdated.next(Math.random())
  }
}

8 Comments

I use the service approach at work and so far it works fine, there isn't too much hassle required to operate it
@some-random-IT-boy : Thank you but not pro in angular just started with it so not sure where to add "@Injectable......"
You should use the angular-cli to generate your service by doing something like: ng generate service {the service name here}
If you are referring to add code to "services" than i asked to do without using "services"
I can't find where you stated that you specified you didn't want to use a service. In any case you have the two alternatives in my answer: The first one is using services (which does the thing @Injectable thing; if you don't want it then feel free to skip it!). What you have left is the "using a parent component" as a data-bridge method
|

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.