0

I am testing an AngularJS website locally. I'm having problems parsing JSON data using $http.get from a local JSON file.

When I define the JSON in my controller, I have no problems. However, when I get the JSON from a file (data.json), the JSON format is different, according to the JavaScript console.

How come the JSON formats are different? Specifically, the $http.get retrieved JSON has numeric keys. Can I simply remove the numeric keys? Or is there something wrong with my JSON declaration/syntax? Below is a slew of additional information.

Here is how I define it in my controller:

$scope.customerReviews = [

        {
            'id': '0',
            'title': 'Outstanding Employee!',
            'text': 'bar foo bar foo',
            'image': '<img class="img-responsive img-hover" src="images/bob.jpg">',
            'href': '',
            'date': 'June 17, 2014',
            'author': 'john',
            'articleType': 'article',
            'neverSettle': 'partnering',
            'category': 'customerReviews'
        },
        {
            'id': '1',
            'title': 'hooray!',
            'text': 'congratulations',
            'image': '<img class="img-responsive img-hover" src="images/bob.png">',
            'href': '',
            'date': 'June 17, 2014',
            'author': 'sir charles',
            'articleType': 'article',
            'neverSettle': 'innovating',
            'category': 'customerReviews'
        },
        {
            'id': '2',
            'title': 'Outstanding Employee',
            'text': 'bar foo foo',
            'image': '<img class="img-responsive img-hover" src="images/bilbo.jpg">',
            'href': '',
            'date': 'June 17, 2014',
            'author': 'johnny',
            'articleType': 'article',
            'neverSettle': 'engaging',
            'category': 'customerReviews'
        },
        {
            'id': '3',
            'title': 'Thank you',
            'text': 'much thanks',
            'image': '<img class="img-responsive img-hover" src="images/x.jpg">',
            'href': '',
            'date': 'June 17, 2014',
            'author': 'The Graduate College',
            'articleType': 'article',
            'neverSettle': 'innovating',
            'category': 'customerReviews'
        }
  ];

When I copy paste from [ to ]; into the Chrome developer tools console, I get the following output:

better picture of controller-declared JSON console output

Like I said above, my current code prints my content perfectly. But if I try to get the JSON in an external file using $http.get, it doesn't print my content, and the JavaScript console shows a different JSON format.

Here is my $http.get code (in the controller):

  // http get json content
  $scope.customerReviews = [];
  $http.get("js/models/data.json").success(function(data){
      console.log("success!");
      $scope.customerReviews = data;
      console.log($scope.customerReviews);
      return $scope.customerReviews;
  });

Here is data.json. As you can see, this JSON file is different from how I define my controller. Specifically, the " and ' are switched to be JSON validation compliant. I ran this one through a JSON validator and it is formatted correctly. Also, when I copy paste this into the console, I get the first console output. Only when I do $http.get I get the "numeric keys" and my printing functions don't work.

[
    {
        "id ": "0 ",
        "title ": "Outstanding Employee! ",
        "text ": "too lazy to obfuscate all of my content",
        "image ": "<img class='img-responsive img-hover' src='images/GladisTolsa.jpg'> ",
        "href ": " ",
        "date ": "June 17, 2014 ",
        "author ": "Martha Castleberry ",
        "articleType ": "article ",
        "neverSettle ": "partnering ",
        "category ": "customerReviews "
    },
    {
        "id ": "1 ",
        "title ": "Facilities Help ",
        "text ": "too lazy to obfuscate all of my content",
        "image ": "<img class='img-responsive img-hover' src='images/FernandoLopez.png'> ",
        "href ": " ",
        "date ": "June 17, 2014 ",
        "author ": "Lucy Valenzuela ",
        "articleType ": "article ",
        "neverSettle ": "innovating ",
        "category ": "customerReviews "
    },
    {
        "id ": "2 ",
        "title ": "Outstanding Employee ",
        "text ": "too lazy to obfuscate all of my content",
        "image ": "<img class='img-responsive img-hover' src='images/MariaAlvarado.jpg'> ",
        "href ": " ",
        "date ": "June 17, 2014 ",
        "author ": "Martha Castleberry ",
        "articleType ": "article ",
        "neverSettle ": "engaging ",
        "category ": "customerReviews "
    },
    {
        "id ": "3 ",
        "title ": "Thank you ",
        "text ": "too lazy to obfuscate all of my content",
        "image ": "<img class='img-responsive img-hover' src='images/MovingServices.jpg'> ",
        "href ": " ",
        "date ": "June 17, 2014 ",
        "author ": "The Graduate College ",
        "articleType ": "article ",
        "neverSettle ": "innovating ",
        "category ": "customerReviews "
    }

]

So the $http.get request works. Here is the console output:

http.get console output

Phew. I apologize for the lengthiness of my question.

My Question: How come the seemingly equivalent JSONs are outputting different formats? Specifically, why does the $http.get retrieved JSON (the second one) have numeric keys? I need the second console output to have the same output as the first console output. Can I just remove the numeric keys? Or is there something wrong with my JSON declaration/syntax?

Any input is appreciated. Especially anything that could improve my AngularJS skills, and JSON knowledge. Thanks in advance.

EDIT: Thanks to everyone so far. Apparently those are array indexes written by Chrome developer tools, not numeric keys. I won't change my post title to avoid confusion for others. On request, here is how my printing works:

   <!-- ng repeat of Blog Preview Rows (reversed) -->
   <div ng-repeat="x in getCategory().slice().reverse() | limitTo:quantity " close="getCategory().splice(index, 1)">
        <previews></previews>
        <hr />
    </div>

getCategory() is a function that gets the querystring of the URL using regex. As stated before, this works when the JSON is declared in the controller. Perhaps getCategory() is ran after $http.get, therefore not printing anything? Also note that I simply reverse the ng-repeat.

Here is the <preview> directive:

.directive('previews', function () {
    return {
        restrict: 'AEC',
        replace: 'true',
        templateUrl: 'js/views/articleCollection.htm'
    };
});

articleCollection.htm:

<div class="row">

<div class="col-md-1 text-center">
        <p><span ng-bind-html="x.articleType"></span></p>
        <p><span ng-bind-html="x.neverSettle"></span></p>
    <p><span ng-bind-html="x.date"></span></p>
</div>
<div class="col-md-5">
    <a href="{{ x.href }}">
        <span ng-bind-html="x.image"></span>
    </a>
</div>
<div class="col-md-6">
    <h3>
        <a href="{{ x.href }}"><span ng-bind-html="x.title"></span></a>
    </h3>
    <p>
        by <span ng-bind-html="x.author"></span>
    </p>
    <p><span ng-bind-html="x.text"></span></p>
    <a class="btn btn-default" href="{{ x.href }}">Read More <i class="fa fa-angle-right"></i></a>
</div>
</div>

Thanks again. Let me know how I can further clarify my question. Also let me know how I can improve anything AngularJS related. So far, the journey has been a doozy.

7
  • What numeric keys? The only numeric keys I see are the array index, which are only part of the developers tools presentation of an array. The output seems exactly the same. Commented Jun 5, 2015 at 20:07
  • It seems that way to me too. Commented Jun 5, 2015 at 20:10
  • I see, so those aren't numeric keys, but array indexes. The output does seem exactly the same, but my existing print functions (which use ng-repeat) don't work with the second one. Do the (lack of) array indexes have to do something with this? Commented Jun 5, 2015 at 20:10
  • The output appears the same, an array with 4 objects. What do you have inside ng-repeat? It should be something like ng-repeat="review in customerReviews track by $index". Commented Jun 5, 2015 at 20:13
  • @dcardoso, My ng-repeat is simple. Pretty much ng-repeat="review in customerReviews, but without track by $index. Commented Jun 5, 2015 at 20:18

2 Answers 2

1

Q: How come the seemingly equivalent JSONs are outputting different formats?

A: Because they are valid either way. See more info of JSON's syntax here

Q:Specifically, why does the $http.get retrieved JSON (the second one) have numeric keys?

A: I am guessing you are talking about the array position index at each array of objects. They make array easier to recognize. Of course, for viewing purpose in console.

Q: I need the second console output to have the same output as the first console output. Can I just remove the numeric keys?

A: Same as above. Google chrome output the 'numeric keys' are just for developers like us to easily recognize the position of array of object. You don't need then in your .json file.

Q: Or is there something wrong with my JSON declaration/syntax?

A: Nope. According to examples your provided, you are doing just fine. Keep up the good work!

EDIT

I've done some research, and, ahhhhhh I see your problem now.

Apparently reading JSON locally cause problem, so you need to modify a little bit.

See this:

AngularJS: factory $http.get JSON file

EDIT 2

Let me give it another go.

I personally have trouble relying on $scope, especially that I would not recommend to return a $scope in a function.

Try this:

app.factory("factoryExample", ['$http', function ($http) {
    return {
        Main: $http.get("js/models/data.json")
    }
}]);

//in controller
app.controller('MainController', ['$scope', 'factoryExample', function ($scope, factoryExample) {
    factoryExample.Main.success(function(data){
        $scope.customerReviews = data;
    });
}]);

As your post mentioned it seems like you are able to get json locally properly, my bad. After this code, your $scope.customerReview should be working!

EDIT3

Give your JSON a name, for your example:

{ "foo": 
    [
        {
            "id ": "0 ",
            "title ": "Outstanding Employee! ",
            "text ": "too lazy to obfuscate all of my content",
            "image ": "<img class='img-responsive img-hover' src='images/GladisTolsa.jpg'> ",
            "href ": " ",
            "date ": "June 17, 2014 ",
            "author ": "Martha Castleberry ",
            "articleType ": "article ",
            "neverSettle ": "partnering ",
            "category ": "customerReviews "
        },
        {
            "id ": "1 ",
            "title ": "Facilities Help ",
            "text ": "too lazy to obfuscate all of my content",
            "image ": "<img class='img-responsive img-hover' src='images/FernandoLopez.png'> ",
            "href ": " ",
            "date ": "June 17, 2014 ",
            "author ": "Lucy Valenzuela ",
            "articleType ": "article ",
            "neverSettle ": "innovating ",
            "category ": "customerReviews "
        },
        {
            "id ": "2 ",
            "title ": "Outstanding Employee ",
            "text ": "too lazy to obfuscate all of my content",
            "image ": "<img class='img-responsive img-hover' src='images/MariaAlvarado.jpg'> ",
            "href ": " ",
            "date ": "June 17, 2014 ",
            "author ": "Martha Castleberry ",
            "articleType ": "article ",
            "neverSettle ": "engaging ",
            "category ": "customerReviews "
        },
        {
            "id ": "3 ",
            "title ": "Thank you ",
            "text ": "too lazy to obfuscate all of my content",
            "image ": "<img class='img-responsive img-hover' src='images/MovingServices.jpg'> ",
            "href ": " ",
            "date ": "June 17, 2014 ",
            "author ": "The Graduate College ",
            "articleType ": "article ",
            "neverSettle ": "innovating ",
            "category ": "customerReviews "
        }

    ]
}

Then use:

<div ng-repeat="items in customerReviews.foo">{{items.id}}</div>

and so on.

Sign up to request clarification or add additional context in comments.

9 Comments

Thank you for the clarifying points. My main question, is why do my print functions work with the first JSON, but not the second JSON, if they are both valid? Answering this question will resolve my post.
Can you show us the code where you print them in your HTML?
According your link, I am possibly running into same-origin policy issues. Unfortunately, I cannot put this project on a web server today. I'll see if that fixes the problem. +1 for your effort.
Updated again. See if it helps.
I get a http://errors.angularjs.org/1.3.15/$injector/undef?p0=factoryExample. I don't know much about factories so I'll look into debugging it.
|
0

Finally got the website on a web server, and the same code threw sce unsafe errors.

I just had to trust it as HTML before returning!

HTML-trustifying helper function:

  function arrayToHTML(data) {
      for (i = 0; i < data.length; i++) {
          data[i]["id"] = $sce.trustAsHtml(data[i]["id"]);
          data[i]["title"] = $sce.trustAsHtml(data[i]["title"]);
          data[i]["text"] = $sce.trustAsHtml(data[i]["text"]);
          data[i]["image"] = $sce.trustAsHtml(data[i]["image"]);
          data[i]["date"] = $sce.trustAsHtml(data[i]["date"]);
          data[i]["author"] = $sce.trustAsHtml(data[i]["author"]);
          data[i]["articleType"] = $sce.trustAsHtml(data[i]["articleType"]);
          data[i]["neverSettle"] = $sce.trustAsHtml(data[i]["neverSettle"]);
          data[i]["category"] = $sce.trustAsHtml(data[i]["category"]);
          data[i]["href"] = $sce.trustAsHtml(data[i]["href"]);
      }
  }

Working Code:

// http get json content
$scope.customerReviews = [];
$http.get("js/models/data.json").success(function(data){
    console.log("success!");
    $scope.customerReviews = data;
    console.log($scope.customerReviews);
    arrayToHTML($scope.customerReviews); // This fixed it!
    return $scope.customerReviews;
});

Comments

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.