Weird behaviour of magically added elements within ion-item

Hi,

I am trying to create a card with a header and multiple avatars within. For some weird reason when i put the avatars inside a custom directive it in run time also adds 2 divs with item-inner and input-wrapper in which a ion-label is placed (which is no where to be found in the actual code) within this ion-label the avatars appear. but because of all the add css by ion-label this goes completely wrong.

I have absolutely no idea why these elements appear out of no where. The code goes as follows:

<ion-item>
        <child-avatar *ngFor="let child of data.children" [child]="child"></child-avatar>
</ion-item>

with child-avatar containing:

<ion-avatar item-start>
  <img [src]="childAvatar" />
</ion-avatar>

however this results in this html code:

<ion-item class="item item-block item-ios">
<div class="item-inner">
<div class="input-wrapper">
<!--bindings={  "ng-reflect-ng-if": "true"}-->
<ion-label class="label label-ios">
        <!--bindings={  "ng-reflect-ng-for-of": "[object Object]"}-->
        <child-avatar ng-reflect-child="[object Object]">
           <ion-avatar item-start="">
           <img src="*removed src*">
          </ion-avatar>
        </child-avatar>        
 </ion-label>
</div>
<!--bindings={ "ng-reflect-ng-if": "false"}-->
</div>
<div class="button-effect">
</div>
</ion-item>

By using [child]=ā€œchildā€, are you not assigning the thing itself as a property? That would result in duplicates would it not? Unless Iā€™m misinterpreting the code

I believe your problem lies in the fact that ion-item is expecting the placement directive (item-start in this case) on a direct child. So I would try putting it on the child-avatar instead of the inner ion-avatar.

Ah, yes. Iā€™m finally catching on to binding properties in Ionic and beyond. [child]=ā€œchildā€ is an attempt to find a source of truth in this case, right?

No, the two instances of child are in completely different scopes. The first one refers to the name of an @Input property on the child-avatar component and the second is a template variable in the parent template (that is looping).

Ok, Iā€™m just now starting to grasp these concepts. I have this in a line I wrote today. It appears similar, achieves the same thing, but in my instance, Iā€™m explicity seeking truth based on the property.

<ion-chip [hidden]="!item.isAnswered"></ion-chip>

Would that be an accurate statement? I can also return other values to a property like

<ion-input [placeholder]="editAnswer(item)"></ion-input>
   if (item.hasBeenRead === true) {
         return "You Have A Pending Question";
       }

        if (item.hasBeenRead === false || (!hasBeenRead)) {
          return "No Pending Questions";
        }
or
 (() => "You Have A Pending Question"));

I can then display that value on the component. Awesommmmme.

Thatā€™s not how I would phrase it. I would say that you are binding the boolean property hidden to the controller expression !item.isAnswered.

Can but generally shouldnā€™t. If at all possible, replace function calls with direct property access (like editPlaceholder or item.editing). Change detection evaluates these expressions very frequently. If you absolutely need a function (if youā€™re embedding some property of item in a printf-style way, for example), do your best to make the function as simple as possible.

Makes sense. I guess something clicked. Thanks man.

1 Like

I actually decided to leave ion-avatar alone and create my own. So no ion-item any more and everything seems to be working fine now. I have found a github bug report reporting the same problem, the answer there is that ion-item expects a ion-label an if its not given one it creates one and wraps the content with it. The only comment there states that ion-item is complex and if its not behaving as you expect you should make your ownā€¦ (which doesnā€™t really seem like a valid answer)

Btw placing a ion-label did not seem to render anything anymore.

i will try this to mark it as an solution for other people

You may wish to revisit this when Ionic 4 comes out. I have seen some comments indicating that this behavior will change.

An interesting take based on todays reference to property binding, on my end

And

I know the connection is not quite obvious, but I certainly had a revelation of sorts today, and took a major leap forward as far as how Iā€™m concepetualizing what it is iā€™m doing.

Many people have gone on and on about finding ā€˜truthā€™ or ā€˜truthyā€™ things. Today, I finally got a glimpse of how simple and powerful the words true and false can be. But, I also see my comment as a reliance on outside sources to ā€œfindā€ truth. When in fact, itā€™s already there, always is, even if itā€™s expressed through something false. Looking at your use of the word ā€˜expressionā€™ in that way blew my mind too. Boolean, and Expression. So simple once it dawns on you. And itā€™s not even a matter of ā€œfindingā€ sources of truth, or boolean, etc., itā€™s a matter of expressing whatā€™s already there. Mind, blown.

Anyways, yes, people tend to complicate things to the nth degree, such as pre-generated components meant to help. Thereā€™s the tie in.

Iā€™ll be un-hijacking your post now, HinderisksR. Sorry.