0

I have successfully used the $http service in angular to pull a JSON object from another server using their API. I was able to then display the values like so...

<div ng-controller="ApiController as ApiCtrl">
{{ApiCtrl.Api.status}}
{{ApiCtrl.Api.meta.count}}
{{ApiCtrl.Api.data[0].nickname}}
{{ApiCtrl.Api.data[0].account_id}}
</div>

This displays the values correctly but I am unable to display the Keys. I read around, here and here. They explained that there is an ng-repeat that is set up to iterate through an object and pull the keys and values from it.

<div ng-controller="ApiController as ApiCtrl">
  <div>
    <div ng-repeat="(key, value) in Api">
        {{key}} : {{value}}
    </div>
  </div>
</div> 

For reference this is the ApiController

function ApiController($http) {
    var vm = this;
    vm.Api = [];

    $http.get('...').success(function (data) {
    vm.Api = data;
    });
};

This is the Json that I requested

{
"status": "ok",
"meta": {
    "count": 1
},
"data": [
    {
        "nickname": "Mitcha47",
        "account_id": 1001356515
    }
]
}

The second method ng-repeat="(key, value) in Api" does not work and only shows * ngRepeat: (key, value) in Api * in the html

Im quite confused about why it doesn't work and am not sure if its an incorrect use of syntax or from not understanding how the ng-repeat fully works.

Edit

After changing to div ng-repeat="(key,value) in ApiCtrl.Api" This was produced ->

 status : ok
 meta : {"count":1}
 data : [{"nickname":"Mitcha47","account_id":1001356515}]'

Which is okay, but not exactly the format to put into a table, which is the next step. Would this be fixed by using the .fromJson function?

Do i include the ApiCtrl because multiple controllers can be used in each module and thus this keeps everything pointing to the correct values?

Community
  • 1
  • 1
Drew Ackerman
  • 241
  • 2
  • 14

3 Answers3

1

You need to specify the controller in your ng-repeat.

EDIT

According to the docs, when you use the controller as declaration methods and properties are bound directly to the controller instead of using $scope hence why you need to specify the controller because the Api object is a property of that controller.

I've changed the snippet to show the data in a table but I am unsure exactly what you want to display. Could you please provide an example?

<div ng-repeat="(key, value) in ApiCtrl.Api">

angular.module("app", [])
  .controller("ApiController", ApiController);

function ApiController($http) {
  var vm = this;

  vm.Api = {
    status: "good",
    meta: {
      count: 42
    },
    data: [{
      nickname: "Timmy",
      account_id: 1
    }, {
      nickname: "Johnny",
      account_id: 2
    }]
  };
};
table {
  border-collapse: collapse;
}

th,
td {
  border: 1px solid black;
  padding: 5px;
}

th {
  text-align: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
<div ng-app="app">
  <div ng-controller="ApiController as ApiCtrl">
    {{ApiCtrl.Api.status}} {{ApiCtrl.Api.meta.count}} {{ApiCtrl.Api.data[0].nickname}} {{ApiCtrl.Api.data[0].account_id}}
  </div>

  <hr>

  <div ng-controller="ApiController as ApiCtrl">
    <div>
      <table>
        <thead>
          <tr>
            <th ng-repeat="(key, value) in ApiCtrl.Api">{{key}}</th>
          </tr>
        </thead>
        <tbody>
          <td ng-repeat="(key, value) in ApiCtrl.Api">
            {{value}}
          </td>
        </tbody>
      </table>
    </div>
  </div>
</div>
Jaydo
  • 1,830
  • 2
  • 16
  • 21
  • A look at my edits and follow up question would be appreciated :) – Drew Ackerman Apr 19 '16 at 05:28
  • @DrewAckerman I've updated the answer but am unsure about what you want to display in the table. You have a `status` and `meta` property and I assume you don't want to repeat those and instead iterate on the `data` property? – Jaydo Apr 19 '16 at 06:06
  • I want to iterate over all Keys and Values, Like it does. The problem is that currently, for example, it displays Key: Data, Value: [{"nickname":"Mitcha47","account_id":1001356515}], with all of the markups like parenthesis. I need it to go into this additional array if it is present, It is in Data and not in status for example, and break these down into readable text without parenthesis or quotes. Ive tried using a JSON.parse but cant seem to get that to work. – Drew Ackerman Apr 19 '16 at 06:09
  • @DrewAckerman How would you like to display that though? Have you thought about a custom filter? – Jaydo Apr 19 '16 at 06:19
  • @DrewAckerman It's easy enough to remove the parentheses and quotes but what about when there are multiple entries? Are you going to repeat "nickname" every time? – Jaydo Apr 19 '16 at 06:20
  • I would prefer not to repeat the key more than once per "user". I have no experiance in creating anything past a directive. The only time I have used a filter was the uppercase one. Would a factory work as well or would a filter be better because I can then just pass the raw data into the filter. Are filters bound to the application they are placed in, as such they should be able to be used in multiple controllers within the same nodule correct? – Drew Ackerman Apr 19 '16 at 06:24
  • @DrewAckerman filters can be bound to a module or a controller (not sure if you can define them inside a factory/service). They can be reused and they are very easy to write. Perhaps you should give it a go and then ask a new question if you still have trouble? – Jaydo Apr 19 '16 at 06:28
  • Thank you for the suggestion Jaydo :) – Drew Ackerman Apr 19 '16 at 06:32
1

Possible problem can be here:

It should be -

    <div ng-repeat="(key, value) in ApiCtrl.Api">
     {{key}} : {{value}}
    </div>

Instead of -

    <div ng-repeat="(key, value) in Api">
     {{key}} : {{value}}
    </div>
pradeep1991singh
  • 8,185
  • 4
  • 21
  • 31
0

If you use the controller as syntax, you have to use

ng-repeat="(key, value) in ApiCtrl.Api"
nonopolarity
  • 146,324
  • 131
  • 460
  • 740