0

I got this rather huge and complex 3rd party JSON, parts of which needs to be displayed in various places on my site. Here is short (believe me, it is short) snippet of that JSON

[
    {
    "EVENTS":[
    {
        "plays":[
        {
            "outcomes":[
                {
                "scoreOrder":1,
                "description":"HOME",
                "remote":"8726401",
                "innings":"2.13"
                },
                {
                "scoreOrder":2,
                "description":"DRAW",
                "remote":"8726403",
                "innings":"3.65"
                },
                {
                "scoreOrder":3,
                "description":"AWAY",
                "remote":"8726402",
                "innings":"2.31"
                }
            ],
            "code":null,
            "acro":"MR",
            "desc":"Result"
            },          
            {
            "outcomes":[
                {
                "scoreOrder":1,
                "description":"No Goal",
                "remote":"8726438",
                "innings":"78.43"
                },
                {
                "scoreOrder":2,
                "description":"Goal in 0-22",
                "remote":"8726434",
                "innings":"1.25"
                },
                {
                "scoreOrder":3,
                "description":"Goal in 23-45",
                "remote":"8726435",
                "innings":"3.89"
                },
                {
                "scoreOrder":4,
                "description":"Goal in 46-67",
                "remote":"8726436",
                "innings":"12.05"
                },
                {
                "scoreOrder":5,
                "description":"Goal in 68-90",
                "remote":"8726437",
                "innings":"37.36"
                }
            ],
            "code":null,
            "acro":"FG",
            "desc":"1st Goal"
            },          
            {
            "outcomes":[
                {
                "scoreOrder":1,
                "description":"Home -0.5",
                "remote":"8726482",
                "innings":"2.13"
                },
                {
                "scoreOrder":2,
                "description":"Away +0.5",
                "remote":"8726483",
                "innings":"1.42"
                }
            ],
            "code":null,
            "acro":"HDMP05",
            "desc":"Handicap"
            }
            ],
        "awayTeam":"Wigan City",
        "order":0,      
        "homeTeam":"Sheffield City",
        "eventStatus":"PENDING"
    }
]

And it's at least ten times longer. As You can see, it consists of few repeating keys. Since it's 3rd party product, I cannot modify it even a bit. Normally, when I didn't use Angular I would go about it like this:

function getJSON(){
    $.getJSON('url/rest/public/app/upcoming?channel=name&amount=1', function(json){
        if (json != null){
            console.log('Load Successful!');
            var events = json[0]['events'];                     
            processEvents(events);
        }
    });
}
function processEvents(events) {     
    events.forEach(function(event){
        var games = event['games'];
        plays.forEach(function(play) {
            var outcomes = play['outcomes'];
            outcomes.forEach(function (result) {
                $('.inning-' + game['acro'] + "-" + result['scoreOrder'] + '-' + event['order']).html(result['innings']);
            });
        });
        $('.inning-AwayTeam-' + event['order']).html(event['awayTeam'].substring(0,3).toUpperCase());
        $('.inning-HomeTeam-' + event['order']).html(event['homeTeam'].substring(0,3).toUpperCase());       
    });     
};

And HTML:

<div class="row-winner">
    <div class="winner-frame inning-MR-1-1"></div>
    <div class="winner-frame inning-MR-2-1"></div>
    <div class="winner-frame inning-MR-3-1"></div>
</div>

But now I need to use angular. From all the tutorials I have studied, none showed me anything else than

site.controller('jsonCtrl', function($scope, $http){
$http.get('url of json').success(function(data){
    $scope.json = data;     
});

});

and

<div class="random-name" ng-repeat="stuff in json | limitTo: 2">                            
    <div class="random-sub-name">{{stuff.key}}</div>                        
</div>

So, not only I don't know how to traverse trough the JSON, but it forces me to use ng-repeat way too often. I know I can narrow the scope of ng-repeat by using something like ng-repeat="stuff2 in json.parent" and then {{stuff2.key}}, which is out of question for the sake of all things, mainly typing, readability of code and my sanity. I also know that ng-repeat may be very handy in many scenarios, especially when I want to display a table of data, but in this particcular case that's not the point. So, still I would prefer something more of a use-once tool, without the need to limit the loop. Anyways, is there any decent way to achieve my goal? Or am I stuck with old jQuery way? And if so, can I use that very jQuery code from within angular's app.js or I need to include another js file with jQuery code and leave angular only to handle ng-include?

EDIT

I forgot to mention that the divs I need to fill generally tend to be individual, non-repeating entities not structurised as a table. They're all over the place. And there's A LOT of them - in total might be well over few hundreds. So putting different ng-repeat directive on each of those divs is simply out of question. My jQuery methods allowed me to accomplish that with relatively low amount of code and custom classes for each div (way shorter than ng-repeat) handling also other duties. I chose Angular for it's swiftness (and I do love concept of hassle-free html loops of ng-repeat), but that scenario requires something more... hardscore. So, help! Please :(

1 Answer 1

1

In angular there is a clear distinction between model and view. If you have a large portion of data in your model, you can preprocess it however you like before it is passed to the view (by assigning it to a field in the scope).

But for the view itself -- in your case displaying a list of events - I strongly encourage you to try to use ng-repeat and alike. What's wrong with something like this:

<div ng-repeat="event in events" class="event">
  <h2>{{ event.homeTeam }} vs. {{ event.awayTeam }}</h2>
  <ul class="plays">
    <li ng-repeat="play in event.plays">
       <div ng-repeat="outcome in play.outcomes">
         Innings: {{outcome.innings}}
       </div>
       <!-- You could also use custom directives to render plays or outcomes -->
    </li>
  </ul>
  and so on...
</div>
Sign up to request clarification or add additional context in comments.

3 Comments

You've focused on a wrong part of JSON. This, let's call it first level keys I got under control. Innings are the problem. For each div displaying different inning or it's same level sibling i would need to go <div ng-repeat="value in events.plays.outcomes | limitTo: 1"> which is unacceptable and doesn't solve the problem of navigating trough different, yet named the same, parts of JSON. In JQuery I would use other keys as a targeting helpers or navigational aides if You will, to help me track down correct keys. And I simply don't know how to do it with ng-repeat or if it's even possible
I updated the answer. You cannot ng-repeat over events.plays.outcomes directly but you can iterate over the outcomes of each play. You just need two nested ng-repeats. It's similar to having two for-loops to iterate over the elements of a nested array.
It still poses one problem (one I may have forgotten to mention explicitly, for which I appologize): ng-repeat despite its awesomeness is no use for me when You need to fill few hundrets of individual cells, each of which takes data from different parts of JSON. I know the whole point of MVC framework is to handle data internally, but here I really can't find a way to do that. jQuery methods I posted are so much faster.

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.