1

I am using KnockoutJS to render a JSON. Certain results have more than 1 "Applications". Is it possible to make it in the foreach so that it only returns 1 only always? Whichever one comes first.

In example below, TEST1 has 2 results under Applications. I would just like to show one in the rendering.

HTML

<table>
<thead>
<tr>
<th>AppId</th>
<th>Name</th>
<th>App Token</th>

</tr>
</thead>
<tbody data-bind="foreach: { data: APPS, as: 'APP' }">
  <tr data-bind="foreach:  Applications">
    <td><span data-bind="text: appId"></span></td>
    <td><span data-bind="text: $parent.name"></span></td>
    <td><span data-bind="text: AppToken"></span>
  </tr>
</tbody>
</table>

JSON

{
   "APPS":{
      "bad":{
         "Name":"TEST1",
         "Applications":[
            {
               "AppId":"bab",
               "AppToken":null
            },
            {
               "AppId":"bab",
               "AppToken":null
            }
         ]
      },
      "good":{
         "Name":"TEST2",
         "Applications":[
            {
               "AppId":"bab",
               "AppToken":null
            }
         ]
      }
   }
}
3
  • Maybe something like data-bind="with: Applications[0]" instead of foreach? Commented Mar 15, 2013 at 17:05
  • Tried it but doesnt seem to work. :-( Commented Mar 15, 2013 at 18:19
  • Did you get an error message? Commented Mar 15, 2013 at 18:20

2 Answers 2

4

APPS is not an Array, so you cannot loop through it. Applications is, you can loop through it. But since you want it to be the first item, just use With binding for both APPS and Applications.

Also, correct the case for your bindings in your HTML. Another thing, the Applications array is off of the "good" or "bad" property of "Apps", so you have to qualify it as such.

Here is a fiddle for the same.

http://jsfiddle.net/sujesharukil/tyJwX/1

<tbody data-bind="with: APPS.bad">
    <tr data-bind="with:  Applications[0]">
        <td><span data-bind="text: AppId"></span></td>
        <td><span data-bind="text: $parent.Name"></span></td>
        <td><span data-bind="text: AppToken"></span></td>
  </tr>
</tbody>
Sign up to request clarification or add additional context in comments.

4 Comments

Only the first binding (AppId) in your fiddle is working. Can you update the fiddle so they're all working?
I wonder why that change made a difference. Seems like both versions should have done the same thing. But +1 for making it work
Well, yes and no. The first version, the context that was passed in does not know the parent, because when I did this data-bind="with: bad.Applications[0], there is no $parent. The context does not exist. When I changed it to this with: Applications[0] and moved bad to the upper level, now I have the context for the parent (which is "bad" property) and hence can now read the "Name" property off of that.
Right... That makes sense. Can't believe I missed that haha
0

Okay, I used:

<!-- ko if: $index() === 0 -->

Got answer from here. knockout.js using $index with if binding

2 Comments

don't do that. You will still be looping through the entire Applications. And if you have let say a few 100 of them, you will loop through, do a condition check for every single item. Instead, just use a data-bind="with: bad.Applications[0]"
This was actually my last resort suggestion if you couldn't get the with binding to work. But it was a last resort for the exact reason @SujeshArukil just pointed out

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.