Getting label from repeater item from different item

Hi all,

I am working on a calendar page in OH3. So far, I have this code snippet:

- component: oh-list-item
  config:
    title: Kalender
- component: oh-repeater
  config:
    for: item
    sourceType: itemsWithTags
    itemTags: Status,Timestamp
    filter: items[loop.item.name].state != "UNDEF"
    fragment: true
    slots:
      default:
        - component: oh-list-item
          config:
            icon: calendar
            iconColor: white
            title: =loop.item.state
            badge: =items[loop.item.name.split('_')[0]+"_dt"].displayState
            badgeColor: black

This produces this ‘image’:

Now, instead of a badge I would rather have a label text. So I tried changing the last component: oh-list-item into component: oh-label-item and instead of badge put the word item. This approach came from one of my other pages where I had label items. But it looks like getting the value from a different item in a label-items does not work. I just get the - at the end of the line.

Anyone any ideas please? Or do I have to stick with the badge?

Btw, the DateTime row is just there till I get my item-properties changed, please don’t comment on that part

loop.item is an object that contains the information returned form a call to the item api. It is not the name of the item or a pointer to the actual OH item. So, within the object that that the repeater returns, there is a label key loop.item.label which will give you the human readable label of the item and there is a name key loop.item.name which will return the string for the name (UID).

ok, I am (still) lost. It does not show but in the part where you would stick item: blah it did put items[loop.item.name.split('_')[0]+"_dt"].displayState. In other words, get the UID name (agenda0_topic), split it at the _, get the first part (agenda0) en stick _dt to the end of it to get an item reference (agenda0_dt) and get that specific displayState. and display that at the end of the label.

I still can’t see why a badge would work and a label does not.

In the oh-label-item the item key takes an item UID. The component then fetches the state of the item (transformed or not as appropriate for the definitions in the state description metadata) automatically. You can’t just switch the badge value (arbitrary string) to the item value (item UID string) because these are two completely different things. for the item just use:

item: =loop.item.name

Ok thanks, I get that part now. But then, could you explain why the badge does show 18:00 while the item itself there contains ‘Vanessa kapper’?

And is there a way to combine this so I get a nice calendar format?

There are two different collections of item data here so it’s important to keep track of which you’re using and what that makes available to you:

  1. As I said above, your loop.item object contains all of the information about the item that would be returned by a call to the item api. This includes all the basic relevant information (e.g., name, label, state, etc.). This does not inlcude any metadata unless you use the oh-repeater’s fetchMetadata option. For each loop through the repeater, this contains only the information about the one item currently being iterated over (there is a second variable which in this case would be loop.item_source which is an array with all the same information for all the items the repeater is looping through should you need to access some item other than the current one).
  2. the items object is a much simpler dictionary that contains only very basic information (just state and displayState essentially), but it has that information for every OH item. The keys for this dict are each of the item UIDs. So this is what you are accessing every time you use the items["Some Item Name Here"].state syntax.

Once you get comfortable with this difference, you’ll be able to get whatever information you need to customize your calendar items however you wish.

You have two different items that you are accessing (and you’re accessing them using the two different methods described above). Based on what you posted earlier, loop.item in this example contains information about the item agenda0_topic. So you can access lots of information about this item: it’s state (which appears to be "Vanessa kapper"), name (agenda0_topic), label (? whatever you put in the label definition of the item), type (String it seems), etc. So when you use

title: =loop.item.state

The title of the list item gets set to the state for agenda0_topic - Vanessa kapper.

However, when you use

badge: =items[loop.item.name.split('_')[0]+"_dt"].displayState

there are several steps. First you use the string of the name of the agena0_topic item and construct a string of the name of an associated item. Now you have a string it that equals "agenda0_dt" it is not an item, it is not an object with item information it is just a string. But you can use that string in the key of the items dict (#2 above) to retrieve the displayState of this other item (18:00).

You should now also see why your badge disappears if your repeater doesn’t return an item. The loop.item.name contains no information if there is no item that has been returned by the api call. If loop.item.name contains no information then you cannot build a recognized second item name string. If you don’t have a actual item name as a string then the call to the items dict will not return anything and the badge will have no text to display.

Wow. Thanks for the elaborate explanation! This helps a lot indeed in constructing these lists. Although I have to read it a few times.

I did post that if I get rid of the item tags in the agenda0_dt item, the badge doesn’t work. I now have removed that post as it appears to work after all :thinking:.

Would I be right that is because a badge just displays a text of course so effectively that is what I am feeding it.

The label is thus tied to the Item that comes forward at that specific row. Would it be possible though to access the ‘next’ item in that label with loop.item_source and also use a visibility prop to hide DateTime items thus only have the _topic items on display? Of so, I still get my label list :grin: otherwise I have to settle with badges.

Yes.

Yes, you can access the loop.item_source from each of the loop’s iterations. It is a zero-indexed array (the first element in the aray is loop.item_source[0]). There is a third variable in the loop object, which in this case would be 'loop.item_idx`. This is an integer telling you which element in the array the repeater is currenly rendering. So to access the next element in the item array you would use:

loop.item_source[loop.item_idx+1]

Without seeing more details on your exact item setup and the end result you are looking for it will be difficult to give any more specific pointers.