1

Question:

Is it possible to define an ng-repeat track by expression which will use a particular attribute if it exists, but use the default $$hashKey behavior if that attribute is undefined?

Context:

I have a chat application which displays an array of JSON "post" objects which have id's. Typically, I would do

<div ng-repeat="post in posts track by post.id">{{post.content}}</div>

However, since I want the app to feel responsive to the user, when a user adds a new chat, I immediately push it onto the array BEFORE I make the create API call. I then update the id if the API response was successful, or update a "failed" field if the API response was not successful.

This means it is possible for the posts array to have multiple post objects which have value undefined for id if there were failed posts.

So I'm hoping it's possible to still use $$hashKey when there is no id defined.

Evan Carslake
  • 2,267
  • 15
  • 38
  • 56
David
  • 335
  • 4
  • 14
  • Not sure about the use of `$$haskey`, but what about giving it a temporary ID? Take last ID +1 or something. Although, I suppose this could give issues if you have a lot of users. – EnigmaRM Aug 27 '15 at 19:35
  • Generate one with a random number. – HankScorpio Aug 27 '15 at 19:48
  • what does `track by post.id` give you that `track by $index` wouldn't in this case? the only thing that `track by` does is ensure that angular can identify a unique row, and `$index` is definitely a unique identifier.... – Claies Aug 27 '15 at 20:46
  • @EnigmaRM: last ID + 1 won't work cause that could conflict with a later post (e.g. if that post fails) – David Aug 27 '15 at 22:37
  • @HankScorpio: hrm... is this suggested? Could this still cause conflicts? or is the probability low enough that it would never matter? – David Aug 27 '15 at 22:37
  • @Claies: There are times when I want to replace a post and not re-render the DOM. I do admit that it isn't that common in this case, but I'm also interested in this question for an application with todo lists (e.g. a list of tasks), which has the same problem. For that case, it would be common to have to replace a task due to new information from the server. – David Aug 27 '15 at 22:39
  • what does that mean, "replace a post and not re-render the DOM"? and how would `track by post.id` make that work when `track by $index` wouldn't? I'm still not clear on what it is you think the difference would be. – Claies Aug 27 '15 at 22:41
  • @Claies: Suppose I were to get a post from the server with updated properties. I want to be able to replace it in the array without re-rendering the DOM. My impression is that by doing `track by post.id`, angular can map the new object to the original DOM. If I were to use $index, I would have to find the position of the post and replace it in the array, right? Would that work if I have an orderBy? – David Aug 28 '15 at 02:43
  • no, that isn't how `track by` works. you would still need to find the item in the array, no matter how you are tracking it in the DOM. – Claies Aug 28 '15 at 05:48
  • @Claies: but would track by $index work with orderBy? it seems like the $index could change in that case. – David Aug 28 '15 at 15:10
  • it wouldn't work with your theoretical code anyway, since you are suggesting that these objects have an `id` that you want to use but don't know what it is yet; when you *do* know what the `id` is, it's just going to mess with the sorting anyway. – Claies Aug 28 '15 at 15:13
  • either way, this really feels like an XY problem; you are asking about how to work with some vague mechanic that you think will solve the problem of inserting a fake object, instead of actually asking about ways to handle fake objects. – Claies Aug 28 '15 at 15:15

0 Answers0