ritz078 / ng-embed

An AngularJS filter/directive for embedding emojis, media, maps, tweets, code and services
http://riteshkr.com/ng-embed
MIT License
122 stars 35 forks source link

Directive broken in ng-repeat with updating list #59

Closed mval1002 closed 7 years ago

mval1002 commented 8 years ago

I'm working on a simple app that has a chat feature. My original goal was to add emoticons, for which the filter feature of ng-embed works great! However, since it's here, I was hoping to include all the other advanced features from this project.

Unfortunately when I use the directive and update the chat list to include previous days' chats, it act strangely. It's hard to explain, so I'm including screenshots, but it seems that the first items in the updated list are overwritten by the items in the original list.

This screenshot shows the original list: embed-screen-1

Updating the list adds 4 new messages, to a total of 6. Because of the odd behavior, the list becomes (5, 6), 3, 4, 5, 6 <-- previous list in ( ) 1, 2, 3, 4, 5, 6 <-- Expected list The original list is overwriting the first two messages of the new list: embed-screen-2

Hopefully this isn't overkill, but to reinforce my findings, after updating the list again and adding 1 more message, the list becomes (5, 6, 3, 4, 5, 6), 6 <-- previous list in ( ) 0, 1, 2, 3, 4, 5, 6 <-- Expected list embed-screen-3

This is very cool module, and I would love to get the most out of it! The filter is already a huge help, and having the advanced embedding features would be amazing.

Thanks!

robman87 commented 7 years ago

Could you post an example of the code you used to generate the list?

mval1002 commented 7 years ago

Sorry, of course!

<div class="chat-wrapper" ng-repeat="message in chat.list | orderBy : 'createdDate' track by $index">
    <div class="chat-message" ng-class="{'self': +message.userId == user.userId}" ng-style="userBg(message.userId);">
        <div class="chat-meta">
            {{message.userName}} <span am-time-ago="message.createdDate"></span>
        </div>
        <ng-embed embed-data="message.message" embed-options="{code:{highlight: fasle},tweetEmbed: false, image: {embed: true}, gdevAuth: 'AIzaSyDCTysHFlNjqaEA3RlpHa4UGqMXHtMoSHY', video: {embed: true, autoPlay: false, details: false}, linkTarget:'_blank'}"></ng-embed>
    </div>
</div>

The chat.list variable is set from a socket event, initially it's simply: chat.list = data; Then upon retrieving the previous day's messages: chat.list = data.concat(chat.list);

Thank you for your assistance!

robman87 commented 7 years ago

It is better to use "track by" with a property that is unique among the objects in the array. $index depends entirely on the position of the item in the array and it changes when you mutate the array. As a first step try the code without "track by" or use message.some_unique_id.

mval1002 commented 7 years ago

Wow, that was embarrassingly simple! I don't even usually use track by, and can't remember why I added it to begin with. It's interesting that it didn't cause any problems with the original basic div output.

Anyway, thank you for taking the time to help! I really do appreciate it!

robman87 commented 7 years ago

Glad to help :)

Track by improves performance since angular will reuse the existing tracked items in the DOM. It's a good idea to use it, specially with directives that are heavy to render, just make sure to use a unique id.

Did this solve your issue or are there more problems?

mval1002 commented 7 years ago

I see, that makes sense. I'll go back and put the track by back with a unique ID. Thank you for the explanation. I'm still learning some of the finer details in Angular, and it helps a great deal to have a concept explained in the context of something I'm working on!

Yes, this issue is resolved now! Thank you again for your help and your patience!