Join the Stack Overflow Community
Stack Overflow is a community of 6.8 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

I manage to parse a json url with java code previously but need to migrate it to javascript now. When I parse using JavaScript, syntaxerror: Unexpected token I occurred

SyntaxError: Unexpected token i in JSON at position 2
at JSON.parse (<anonymous>)
at success (homeCtrl.js:1060)
at processQueue (ionic.bundle.js:29127)
at ionic.bundle.js:29143
at Scope.$eval (ionic.bundle.js:30395)
at Scope.$digest (ionic.bundle.js:30211)
at Scope.$apply (ionic.bundle.js:30503)
at done (ionic.bundle.js:24824)
at completeRequest (ionic.bundle.js:25022)
at XMLHttpRequest.requestLoaded (ionic.bundle.js:24963)
(anonymous) @ ionic.bundle.js:26794
(anonymous) @ ionic.bundle.js:23507
processQueue @ ionic.bundle.js:29135
(anonymous) @ ionic.bundle.js:29143
$eval @ ionic.bundle.js:30395
$digest @ ionic.bundle.js:30211
$apply @ ionic.bundle.js:30503
done @ ionic.bundle.js:24824
completeRequest @ ionic.bundle.js:25022
requestLoaded @ ionic.bundle.js:24963 

My javascript is as below:

//scrap singapore
function topVolumeGainerLosersSingapore(type) {
$ionicLoading.show();

var url = "http://www.sgx.com/JsonRead/JsonData?qryId=RStock&timeout=30";

$http({
method: 'GET',
url: url,
transformResponse: undefined,
headers: {
"Content-Type":"text/plain",
"Accept":"text/plain"
}
}).then(function success(response) {
// this function will be called when the request is success
var text = response.data;
//console.log(text);
var replaceData = text.substring(text.indexOf("&&")+2);
//console.log(replaceData);
var newData = JSON.parse(replaceData);
console.log(newData);

}, function error(response) {
// this function will be called when the request returned error status
$ionicLoading.hide();
console.log(response);
});
}

The java code can parse correctly with no error for the same url

public class MainActivity extends AppCompatActivity {

    private static final String TAG = MainActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        new AsyncTas().execute();
    }

    private class AsyncTas extends AsyncTask<Void,Void,Void>{

        @Override
        protected Void doInBackground(Void... voids) {
            HttpURLConnection urlConnection = null;
            String urlString = "http://www.sgx.com/JsonRead/JsonData?qryId=RStock&timeout=30";
            try {
                urlConnection = (HttpURLConnection) new URL(urlString).openConnection();
                //String result = readIt(new BufferedInputStream(urlConnection.getInputStream()));
                BufferedReader bufferedReader = new BufferedReader(
                        new InputStreamReader(urlConnection.getInputStream()));

                // Grab the results
                StringBuilder log = new StringBuilder();
                String line;
                while ((line = bufferedReader.readLine()) != null) {
                    log.append(line + "\n");
                }
                String result = log.toString();

                result = result.substring(result.indexOf("&&") + 2);
                JSONObject jo = new JSONObject(result);

                Log.e(TAG, "doInBackground: "+result);
            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
                Toast.makeText(getApplicationContext(),"Unable to parse json "+e.getMessage(),Toast.LENGTH_LONG).show();
            }
            return null;
        }
    }
}

The desired output is as below:

{identifier:'ID', label:'As at 08-03-2017 2:48 PM',items:[{ID:0,N:'3Cnergy',SIP:'',NC:'502',R:'',I:'',M:'t',LT:0.000,C:0.000,VL:0.000,BV:100.000,B:'0.042',S:'0.047',SV:70.000,O:0.000,H:0.000,L:0.000,V:0.000,SC:'2',PV:0.040,PTD:'20170307',BL:'100',EX:'',EJ:'',CLO:'',P:0.0,P_:'X',V_:''},{ID:1,N:'800 Super',SIP:'',NC:'5TG',R:'',I:'',M:'t',LT:1.160,C:-0.020,VL:51.400,BV:10.500,B:'1.160',S:'1.170',SV:10.000,O:1.180,H:1.180,L:1.160,V:60324.500,SC:'A',PV:1.180,PTD:'20170307',BL:'100',EX:'',EJ:'',CLO:'',P:-1.694915234375,P_:'X',V_:''},{ID:2,N:'8Telecom',SIP:'',NC:'AZG',R:'',I:'',M:'',LT:0.000,C:0.000,VL:0.000,BV:5.000,B:'0.130',S:'0.140',SV:10.000,O:0.000,H:0.000,L:0.000,V:0.000,SC:'2',PV:0.135,PTD:'20170306',BL:'100',EX:'',EJ:'',CLO:'',P:0.0,P_:'X',V_:''},{ID:3,N:'A-Smart',SIP:'',NC:'BQC',R:'',I:'',M:'',LT:0.570,C:-0.020,VL:60.000,BV:31.000,B:'0.570',S:'0.580',SV:10.000,O:0.575,H:0.575,L:0.570,V:34350.000,SC:'2',PV:0.590,PTD:'20170307',BL:'100',EX:'',EJ:'',CLO:'',P:-3.38983046875,P_:'X',V_:''}, 
share|improve this question

It seems like the source data doesn't contain valid JSON data. According to http://json.org/ a key is a String and therefore must be wrapped in double quotes, which also applies to the String values:

{ "identifier": "ID" }

As your error states, the parser was expecting a double quote, rather then the i character.

I suggest you test your code with a small snippet first to verify it works with valid JSON data.

share|improve this answer
    
but it works in java, why? – bkcollection 18 hours ago
1  
Because Java does not expect strict mode JSON: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… – Björn M 18 hours ago
    
Thats the difference between JSON.parse and eval(). The first one expects strict JSON and the other one JavaScript. You source data is written in the last format. See w3schools.com/js/js_json_syntax.asp – Albert-Jan Verhees 18 hours ago
    
@BjörnM, any workaround that you can suggested? Thanks – bkcollection 18 hours ago
    
I think @holi-java has provided that in his answer – Albert-Jan Verhees 18 hours ago

use eval instead.your json data is not a strict mode.a strict mode json data the key must be double-quoted.

Demos

var json="{} && { identifier: 'ID' }";

function test(json,parser){
  try{
  console.log("parsing by "+parser.name+" => "+JSON.stringify(parser("("+json+")")));
  }catch(e){
    console.log('Can not parsed by '+parser.name);
  }
}
test(json,JSON.parse);
test(json,eval);

JSON.parse only supported strict mode

var formats={
 strict:'{"foo":"bar"}',
 'single-quotes':"{'foo':'bar'}",
 'no-quotes':"{foo:'bar'}"
};

function test(parser){
  return parser.name+" supports " +Object.keys(formats).reduce(function(supports,format){
    try{
       parser(formats[format]);
       supports.push(format);
    }catch(e){      
    }finally{return supports;}
  },[]);
}
function parseJSON(json){
 return eval("("+json+")");
}
console.log(test(parseJSON));
console.log(test(JSON.parse));

Encapsulate eval() solve the security problem.

window.$ = window.jQuery = {};
function foo() {
    return 'bar';
}

parse = (function () {
    //disable all global keys
    eval("var " + Object.keys(window).join(', '));

    return function (_) {
        return eval("(" + _ + ")");
    };
})();


var snippets = [
    "window",
    "location",
    "$",
    "jQuery",
    "location.href='http://www.example.com'",
    'local',
    "{foo:'bar'}",
    "foo()",
    "eval('window')",
    'function ref(){return window}()'
];
snippets.forEach(function (snippet) {
    var local = 'local value';
    var expression = "parse(" + JSON.stringify(snippet) + ")";
    try {
        console.log(expression + " => " + JSON.stringify(parse(snippet)));
    } catch (e) {
        console.error(expression + " failed!");
    }
});

share|improve this answer
    
Eval() should not be used for JSON parsing both for security and efficiency reasons. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…! – Björn M 18 hours ago
    
I just solve his problem in legacy json format. – holi-java 18 hours ago
    
@BjörnM eval has security problem,but you can encapsulate it to disallowed access others only global variables can access. – holi-java 18 hours ago
    
In my opinion simply fixing the input is more sustenaible than a complicated legacy solution. As I understand it the questioner is creating the JSON, so it it possible to fix it before the baby falls into the well instead of getting it out afterwards. If there is no way out your solution solves legacy parsing. – Björn M 13 hours ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.