Binding expression to interpolation?

Is there a work around to bind an interpolation to an expression?

<ion-segment [(ngModel)]="something" (ionChange)="onChange($event)">
  <ion-segment-button *ngFor="let some of things" value="{{some | json}}" [myDataToBind]="{{some}}">
    {{some.label}}
  </ion-segment-button>
</ion-segment>

Possibly with ion-segment, or any custom ionic component? I really just want to send the entire object over, which I can do in the above with using a pipe on value, but I rather use a proper of the object as a string.

Can you describe a bit more what youā€™re trying to achieve? Iā€™m having a hard time understanding how that proposed syntax should be parsed.

Sure - what Iā€™m really trying to do is when a user selects an option - ie. ion-option, ion-segment-button, etc - the onChange/ionChange/custom event would not only send the value of the option, but carry an entire object over as well.

So in this example, if you select an ion-segment-button, I want to pass a big ole json object to the onChange event, somehow ā€¦ dynamically. Sounds foolish as I say it, not not even sure possible.

If Iā€™m understanding you correctly, what happens if you swap [value]="some" in where you currently have value="{{some | json}}"?

yeah, for value I just really want a string, or value="{{some.slug}}" so I can track what options are being selected instead of passing the entire object in.

normally I thought data-some="{{some}}" would work in some way as a data attribute, but not wrapping my head around it.

This seems contradictory to me. You say you want to pass an entire object, [value] offers you a way to do that, but then you donā€™t want to do that. Iā€™m baffled at this point.

What about making your function (ionchange)=ā€œonchange($event, this.some)ā€ or ($event, some)?
Might be able to get the result you want by including the original object?

I will try this out, didnā€™t occur to me I could pass more than one parameter. Well, how would I however? Some is part of the ngFor loop within the ion-segment-button, whereas the event is being declared at the ion-segment? Nonetheless I will give it a go.

Fair enough. I wasnā€™t able to set a default value for the options of ion-segment by passing in a whole object. I suppose I could also try and see if ``[selected]=ā€œsomeCheck($event)ā€``` it does the trick.

Make sure you are using the exact same object, not a clone with similar properties. See framework #6225 for more context.

This may be a hacky way to get this result, but (for me also), ion-option and ion-select are a little tricky.
I have an ion-select that pulls up a list of venues. The pageā€™s constructor has an object called this.venues. My html [(ngModel)] =ā€œvenueā€, and change event is (ngModelChange)=ā€œselChange($event, ā€˜venuesā€™)ā€.
hereā€™s the html
ion-select name=ā€œvenueā€ [(ngModel)]=ā€œvenueā€ (ngModelChange)="selChange($event, ā€˜venuesā€™)"
ion-option *ngFor=ā€œlet venue of venuesā€
{{venue}}
ion-option
ion-select

In my case, the page/component is called TicketsPage.
My function on TicketsPage.ts

selChange(event:any, x) {
console.log(this[x]);
}

So console.log(this[x]) is console.log(TicketsPage[this.venues], and i get this.venues, the original object).Hacky, but it works. At that point, you have the original object to do what you will.

There has got to be a cleaner solution for your situation. Can you share more code so that we can understand better whatā€™s going on?

yeah. Just realized there was a much simpler approach and changed my reply, but it still gets ā€˜thisā€™ involved. Not good, but itā€™s the only thing I can come up with.

Thanks for spending time on it, so hereā€™s my dom -

<ion-segment [(ngModel)]="something" (ionChange)="onChange($event)">
  <ion-segment-button *ngFor="let item of somethings" value="{{item | json}}">
    {{item.label}}
  </ion-segment-button>
</ion-segment>

Now when you select an option, item is bound to something as the correct json.

But in my constructor, I just want to set the default item by object, not string field. compareWith doesnt work with ion-segment.

constructor(private svc: ServiceProvider) {
  svc.getData().then(data => {
      this.something = data[0]; 
      this.somethings = data; // an array of objects
  });
}

I suspect data[0] is NOT equal to the DOMs value="{{item | json}}"? So I guess my real problem is setting the default value for the ion-segment when value is an object.

So the work around is that I set each ion-segment-button value="{{item.slug}}", and then I just find which object it is by filtering and reducing from the original data when itā€™s selected -

getRaw(o): Promise<any> {
    let tmp = this.somethings.filter(item => item.slug === (o && o.value)).reduce((acc, cur) => cur, {});
    return Promise.resolve(tmp);
}

Just feels bloatedā€¦

I donā€™t understand the fixation on making the value a string by passing item to the json pipe, but if you insist on doing that, you are going to have to set the default value similarly. Furthermore, that seems very brittle, because you have to rely on the JSON stringification process working exactly the same way.

What you say you are fundamentally trying to do (use an object as the default value) is possible. For example,

optionsPlatos: FoodItem[] = [
  {name: "Sencillo", price: 100},
  {name: "Normal", price: 200},
];

plato: FoodItem;

constructor() {
  this.plato = this.optionsPlatos[1];
}

<ion-select [(ngModel)]="plato">
  <ion-option *ngFor="let dish of optionsPlatos" [value]="dish">{{dish.name}}</ion-option>
</ion-select>

You should see ā€œNormalā€ as the default value of the select.

1 Like

Apologies for making you go around in circles - didnt wrap my head around your prior claim about [value]doing the trick. I thought it was a typo, because ā€œdishā€ wasnā€™t being declared anywhere inside my .ts file. So it appears that when you set value as an input, [value] - the expression is coming from within the *ngFor directive. :dizzy_face: whoosh

Thatā€™s one possibility. It can be an expression involving both template variables (such as something coming from an ngFor) or a property (or even the result of a function) defined in the controller. Generally you want to keep it as simple as possible for both performance (these get evaluated a lot of times due to change detection) and readability, but any input properties can be full-on template expressions. For more detail, see the template expression section of the syntax docs.