3

I have bunch of for loops in php which feed folder names and file locations to a 6 dimensional array. Here is the code behind the loops: https://gist.github.com/anonymous/66aa7cabe47f91eda6835e193d04a92d

I have a single page application which displays information based on these folder names/ array size. These are the folder levels I need to traverse through:

  • Environment (of which there are 4)
  • Feature name (of which is an undefined value)
  • Day (date - of which is an undefined value)
  • Time (timestamp - of which is an undefined value)
  • Report Link (file location of an html file on the server ^ based on above folder structure - of which is an undefined value)
  • .json file location on the server ^ based on the above folder structure - of which is an undefined value

I have written some php code which json_encodes the $folderStructure array and then json_decodes it to a nice readable format:

<?php

    require('data.php');

    $data = json_encode($folderStructure); // decode the JSON into an associative array

    $changed = json_decode($data, true);

    echo '<pre>' . print_r($changed, true) . '</pre>'; // This will print out the contents of the array in a nice readable format

?>

And the output is: https://gist.github.com/anonymous/944e97b98596454a27cc8236a4420dbd

As you can see, there is a lot of data. As the size of the array will increase, the loading of the data will take longer. I have been suggested to use AngularJS to display the page contents (as opposed to what I have currently - https://gist.github.com/anonymous/429747625b113df0bed30c727a338ffe (which is very very inneficient). Dicionaries are apparently a lot faster to traverse and thus the sensible solution is to convert this single page application to be written in AngularJS.

I have experiemented with the below:

<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<body>

<div ng-controller="controllerName">
    <ul>
        <li ng-repeat="(environment, number) in items">{{environment}}: {{number}}</li>
    </ul>

</div>

    <script>
        angular.module('app', [])
            .controller('controllerName', function($scope)
            {
                $scope.items = {'DEV':10, 
                                'Production':12
                                ,'Staging':10
                                ,'QA':12

                                };
            });
    </script>
</body>
</html>

And wondered whether it would be possible for me to convert my PHP array into one of these items objects and use ng-repeat to display the information rather than PHP. Is this something than can be achieved? I'm a bit stumped as to how to achieve this, would anyone be able to help me out with this?

EDIT: My current PHP solution works but is however slow as it relies on arrays. What I wanted to achieve is something that looks similar to this: enter image description here except to be written in AngularJS (using a ng-repeat from a dictionary) instead of for loops in PHP.

So to put it in black and white, based on my current design: https://gist.github.com/anonymous/429747625b113df0bed30c727a338ffe - how can I convert the $folderStructure array into some sort of object or dictionary and use that to display information on the page using ng-repeat?

EDIT 2: Why would json_encode not work? JSON is Javascript Object Notation. Well, okay. How do I pass in the value of the array into: $scope.items and create a name value pair without hardcoding the values myself? 1) I don't know the folder names after the initial environment array position of $folderStructure as they change all the time. 2) I don't know how big the array will be in the future either.

EDIT 3:

I've altered some code in index.php to look like this:

<!DOCTYPE html>
<html ng-app="myApp">
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    </head>
    <body>

        <div ng-controller="myCtrl">

            <p>{{myStuff}}</p>

        </div>

        <script>
            var app = angular.module('myApp', []);

            // get the data using a http request
            app.controller('myCtrl', function($scope, $http) 
            {
                $http.get("php/get_data.php").then(function (response) 
                {
                    $scope.myStuff = response.data;
                });
            });


        </script>
    </body>
</html>

Problem is, the output for myStuff is literally this: pastebin.com/CyiZ5UhG

Is there a way for me to iterate through this ouput and use ng-repeat for each of the headers (without me knowing what the headers are)?

4
  • Why would json_encode not work? JSON is Javascript Object Notation.. Commented Oct 26, 2016 at 14:45
  • Alight @Devon , but would you be able to explain to me how I would be able to traverse through the json in order to have an ng-repeat for each array position? ie ideal output: 4*EnvironmentName, x* featureName, x* dayName etc? Commented Oct 26, 2016 at 14:47
  • could you provide the result of <<< json_encode($folderStructure); >>> to improve my answer Commented Oct 26, 2016 at 14:56
  • @swordf1zh Hi, thanks for the reply. Please see this: pastebin.com/CyiZ5UhG - result of echo json_encode($folderStructure); Commented Oct 26, 2016 at 14:58

2 Answers 2

0

You can nest ngRepeat like this:

<div ng-repeat="item in items">
  <div ng-repeat="itemChild_level1 in item">
    <div ng-repeat="itemChild_level2 in itemChild_level1>
      ...
      <p>{{ itemChild_levelX.property</p>
    </div>
  </div>
</div>
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the answer. Would you be able to improve on your solution based on EDIT 3 of my question please? As your solution only covers a slight portion of what I wanted to achieve.
0

Well, i´m going to try to keep it short;

I think that your problem is how to inject the json, and the easiest for you would be to inject it this way:

    <script>
        angular.module('app', [])
            .controller('controllerName', function($scope, $datasources){
                $scope.items = $datasources["dataset1"];
            }).value("$datasources", {
               dataset1:<?php echo json_encode($data); ?>,
            });
    </script>

However, I would suggest you further reading about angular services. What I would do instead of this, is to create a service that retrieves that data through $http directive, and call it inside the controller declaration like this:

            .factory("DataService", function($http, $q){
                return{
                    get:function(){
                       var deferred = $q.defer();

                       $http.get("urlWithData").then(function(data){
                          deferred.resolve(data)
                       }, function(error){
                          deferred.reject(error);
                       })
                       return deferred.promise;
                    }
            })
            ....
            .controller('controllerName', function($scope, DataService){
                DataService.get().then(function(data){
                     $scope.items = data;
                });
            })

EDIT:

The html code to iterate through your records (use it as a hint, honestly, not going to study the structure of that code in pastebin ^^):

<!DOCTYPE html>
<html ng-app="myApp">
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    </head>
    <body>

        <div ng-controller="myCtrl">

            <ul>
                 <li ng-repeat = "(index, item) in myStuff">
                      <ul ng-if = 'typeof item == 'Array'">
                          <li ng-repeat = "(subindex, subitem) in item"></li>                        
                          etc ...
                      </ul>
                      <p ng-if= "typeof item == 'String'">{{item}}</p>
                 </li>
            </ul>

        </div>

        <script>
            var app = angular.module('myApp', []);

            // get the data using a http request
            app.controller('myCtrl', function($scope, $http) 
            {
                $http.get("php/get_data.php").then(function (response) 
                {
                    $scope.myStuff = response.data;
                });
            });


        </script>
    </body>
</html>

BTW, why such a deep nesting in your data?? seems needlessly complicated

2 Comments

Thanks for the answer. Would you be able to improve on your solution based on EDIT 3 of my question please? As your solution only covers a slight portion of what I wanted to achieve.
I will try... but not sure about the problem you have with it. I´ll assume that when you say "literally" you mean the content of the refered link, and not the text itself :)

Your Answer

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