27

I Have looked all over SO and Google but have have noting that has helped and I'm unsure how to continue. I have an array which I am returning from a php page using echo json_encode() that looks like this:

[" "," "," "," "," ",1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]

but I keep getting Unexpected token o at Object.parse (native) when I try to use JSON.parse() and Unexpected token o at Function.parse (native) when I use the JQuery alternitive.

but when I just attach it to the $scope I can print it out using on the page, so What am I doing wrong and how can I correct this?

this is my controller

function myController($scope, memberFactory) {

    response = memberFactory.getMonth("2013-08-01 06:30:00");
    //$scope.response = response;
    var monthDays = $.parseJSON(response);

    var dates = [];
    for (var i = 0; i < monthDays.length; i++) {
        if (i % 7 == 0) dates.push([]);
        dates[dates.length - 1].push(monthDays[i]);
    }
    $scope.dates = dates;
    //
}

this is my Service Method:

obj.getMonth = function (date) {
    var month = $q.defer();
    $http.get('getMonth.php?date=' + date)
        .success(function (data, status, headers, config) {
        month.resolve(data);

    });

    return month.promise;
}

and this is my php:

<?php $daysOfMonth=[ " ", " ", " ", " ", " ",1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31];
echo json_encode($daysOfMonth); ?>

Things I have Tried

If I return the typeof I get Object, so I have then tried var monthDays = Array.prototype.slice.call(response) and var monthDays = $.map(response, function (value, key) { return value; });as suggested in some of the answers here, I have also tried JSON.stringify() but I just get {} as the result

I am really frustrated with this an really need someone to point me in the correct direction

Update

I believe this may be an issue with using $q.defer() as I updated my getMonth Method as follows:

obj.getMonth = function (date) {
    var month = $q.defer();
    $http.get('getMonth.php?date=' + date)
        .success(function (data, status, headers, config) {
        month.resolve(data);
        console.log("data " + data[0]);
        console.log("resolved " + month.promise[0]);

    });

    return month.promise;
}   

now I get 1 for console.log("data " + data[0]); as expected but I get for console.log(month); I get [object Object] forconsole.log(month.promise) I get [object Object]and for console.log(month.promise[0]); I get undefined

Community
  • 1
  • 1
jonnie
  • 12,260
  • 16
  • 54
  • 91

4 Answers4

65

response is already parsed, you don't need to parse it again.

If you parse it again it will perform a toString-cast first so you're parsing

"[object Object]"

which explains the unexpected token o.

Halcyon
  • 57,230
  • 10
  • 89
  • 128
  • 1
    So how do I access the values, I tried using response[0] but no luck, I tried `Object.keys(response)` to get the keys, it returns `then` and response["then"] returns nothing – jonnie Aug 08 '13 at 15:42
  • Do `console.log(response);` to see what it looks like. `response[0]` should work if you're getting that Array back. – Halcyon Aug 08 '13 at 15:43
  • for `console.log(response)` I get `[object Object]` , for `console.log(response[0])` I get undefined , If I attach to scope like this `$scope.response = response` then `{{response}}` appears as `["","","","","",1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]` – jonnie Aug 08 '13 at 15:48
  • That doesn't look right at all .. can you verify that you've not got a 2nd hidden parse somewhere? – Halcyon Aug 08 '13 at 15:49
  • no 2nd parse, I've removed them all – jonnie Aug 08 '13 at 15:50
6

Please take a look a the chapter Transforming Requests and Responses of the $http module.

If JSON response is detected, deserialize it using a JSON parser.

Since it is already parsed as JSON object, if you parse it again, you will get that error.

Here is a simple test:

response = '{"a": "a","b": "b"}';
var obj = $.parseJSON(response);
console.log(obj); //Object {a: "a", b: "b"} 
$.parseJSON(obj)  //Uncaught SyntaxError: Unexpected token o 
zs2020
  • 53,766
  • 29
  • 154
  • 219
1

This was resolved with help of @CuongLe here by replacing

 response = memberFactory.getMonth("2013-08-01 06:30:00");
 var monthDays = $.parseJSON(response);

with:

response = memberFactory.getMonth("2013-08-01 06:30:00");
response.then(

function (monthDays) {
    console.log("monthDays : " + monthDays + " !!!");

    var dates = [];
    for (var i = 0; i < monthDays.length; i++) {
        if (i % 7 == 0) dates.push([]);
        dates[dates.length - 1].push(monthDays[i]);
    }

    $scope.dates = dates;
});
Community
  • 1
  • 1
jonnie
  • 12,260
  • 16
  • 54
  • 91
1

If the header is sent:

Content-Type: text/json

Then parseJSON() does not need to be called. For example:

In a PHP I would set the header like this:

<?php
header("Content-Type: text/json");
echo json_encode(array("someKey" => "someValue"));

And in Javascript I would have something like this for the success function:

success: function(response) {
// This will output "someValue" to the console.
// Note the lack of the parseJSON() call. parseJSON() is called for us because the header was sent as text/json
console.log(response.someKey);
}
Isaiah Turner
  • 2,574
  • 1
  • 22
  • 35