12

Here is my issue: The datatable plug-in only accepts an array I believe but my API returns an object with an array. I am trying to figure out if I need to extract this info (how?) or if the plug-in has some methods that do that for me (there is one):

    //the datatable plugin expects the following JSON structure
        [
            {
                "ID":"a5f415a7-3d4f-11e5-b52f-b82a72d52c35",
                "Record":1,
                "HostName":"SRX552P"
            }
        ]

    //my PHP server returns the following JSON structure:
        {
            "status":"success",
            "message":"data retrieved",
            "data":[
                    {
                        "ID":"a5f415a7-3d4f-11e5-b52f-b82a72d52c35",
                        "Record":1,
                        "HostName":"SRX552P"
                    }
                   ]                
        }    

    var allData = null;
    //this is my angularjs service where I am grabbing all the 'data':
        function getAllData() {
            dataservice.get('table001').then(function(data){
                allData = data;
            });         
            return allData;
        }

    //it looks like my issue is exactly what this post describes:
    http://stackoverflow.com/questions/27797435/accessing-json-data-in-angularjs-datatables-using-dtoptions

    //but applying ".withDataProp('data.data')" didn't work for me:
        ...
            this.standardOptions = DTOptionsBuilder
                .fromFnPromise(getAllData())        
                .withDataProp('data.data')
                //.fromSource('api/tables/datatables.standard.json')    //static data works fine!                      
                 //Add Bootstrap compatibility
                .withDOM("<'dt-toolbar'<'col-xs-12 col-sm-6'f><'col-sm-6 col-xs-12 hidden-xs'l>r>" +
                    "t" +
                    "<'dt-toolbar-footer'<'col-sm-6 col-xs-12 hidden-xs'i><'col-xs-12 col-sm-6'p>>")
                .withBootstrap();              

            this.standardColumns = [
                DTColumnBuilder.newColumn('ID'),
                DTColumnBuilder.newColumn('Record'),
                DTColumnBuilder.newColumn('HostName')
            ]; 
        ...

//this is the service
(function () {
    'use strict';
    angular.module('app.ipxtool').factory('dataservice', dataservice);
    dataservice.$inject = ['$http', '$q'];    

    function dataservice($http, $q) {        
        var serviceBase = 'api/v1/';
        var obj = {};        
        obj.get = function (q) {
            return $http.get(serviceBase + q).then(success).catch(fail);
        };         

        function success(results) {             
            if (results.data.status == "error") {
                logger.error(results.data.message, '', 'Error');    //$response["data"] = null for errors;
            }              

            if (results.data.status == "warning") {
                logger.warning(results.data.message, '', 'Warning');
            }                      

            if (results.data.status == "success") {
                logger.success(results.data.message, results.data.data, 'Success'); //$response["data"] = $rows;               
            }                
            return results.data; 
        }

        function fail(e) { 
                return (e); 
        }                                                
        return obj;   
};
})();

Using Fiddler I can see all the data being returned. Also I output the first array item as follows:

console.log("var allData: " + "[" + JSON.stringify(alldata.data[1]) + "]");

enter image description here enter image description here

Cœur
  • 37,241
  • 25
  • 195
  • 267
Max
  • 1,289
  • 3
  • 26
  • 50
  • 1
    Your array should be in `data.data` (without the `[1]`). Are you able to edit the back-end? I'm assuming you're using CakePHP based on that output. You can get it to output an array with a little tweaking. – jperezov Feb 17 '16 at 20:36
  • I am using Slim - a micro PHP 5 framework. What is the tweak? – Max Feb 17 '16 at 20:59
  • I can now see the output by adding allData = JSON.stringify(data.data); I see the correct format but the datatable still won't accept it :-( – Max Feb 17 '16 at 21:08
  • If you do `allData = JSON.stringify(data.data)`, the `allData` variable will contain a string, not an array. Before the line `dataservice.get` (in `getAllData`), declare the `allData` variable with `var allData;`, then do `allData = data.data`. Alternatively, you can try `.withDataProp('data.data')`. – jperezov Feb 17 '16 at 21:25
  • Did you verify that this works using a plain-text JSON file? i.e. copy the "expected structure" into someFile.json, and change your ajax call to hit somefile.json. Also, I've never used Slim, but you could try to just set a `die(json_encode($yourData));` to ensure it comes out in the structure you expect. You might need to add `header('Content-Type: application/json');` before the die statement. – jperezov Feb 17 '16 at 21:58
  • yes sir, look at line: //.fromSource('api/tables/datatables.standard.json') – Max Feb 17 '16 at 22:24
  • How does your `dataservice` factory look like? There is certainly something wrong going on. – davidkonrad Feb 22 '16 at 14:14
  • David, I edited the text and added the service code. I mentioned before that when I trace the call I can see all the data structure being returned by the service. – Max Feb 22 '16 at 15:30

2 Answers2

6

The solution to this issue was to add the following:

.fromFnPromise(function() {
     return dataservice.get('table001');
})

Not sure why calling getAllData() didn't work. So finally I got this thing resolved. Thanks.

chalasr
  • 12,971
  • 4
  • 40
  • 82
Max
  • 1,289
  • 3
  • 26
  • 50
  • You could probably do the same with `return dataservice.get('table001')` (?) dataTables looks for a promise and wait for it to be resolved by `_loadedPromise.then(function(result) {` if you return `dataservice.get('table001').then(function(data){` then you actually do what dataTables wants to do : Wait for the resource to be ready and pass the data back. – davidkonrad Feb 24 '16 at 15:13
0

You can add [ and ] at the start and at the end of your output var in php page itself, so that it would return a proper JSON output. Since I also faced such issue earlier in Angular as it doesn't accept direct Object input, I used the above approach to convert it into full-fledged JSON.

Also add the below code at the top of your PHP page:

header('Content-Type: application/json');

So that, it'll return the content in JSON-formatted text.

Andrey Ermakov
  • 3,298
  • 1
  • 25
  • 46
Himanshu Aggarwal
  • 1,060
  • 8
  • 13
  • the PHP is already returning JSON format. Adding [ ] would not be a solution as I also need the object. By accessing the data.data portion will give me the array I need. – Max Feb 26 '16 at 23:41