React Native JSON Parse error Unexpected identifier

I'm trying to get the location from my cellphone and then send it to an API, so far everything works well untill I try to access each individual value of the data.

So far this is my code.

import React, { useEffect, useState} from "react";
import { StyleSheet, View, Text, TouchableOpacity } from "react-native";
import MapView, { Marker }from "react-native-maps";

import * as Location from 'expo-location';
import * as Permissions from 'expo-permissions';

const Untitled1 = (props) => {

  const [errorMessage, setError] = useState(null);
  const [location, setLocation] = useState(null);

  useEffect(() => { 
   (async () => {
    let { status } = await Permissions.askAsync(Permissions.LOCATION);
    if (status !== 'granted') {
      setError({
        errorMessage: 'Ubication service was denied',
      });
    }
    let location = await Location.getCurrentPositionAsync({accuracy:Location.Accuracy.Highest});
    setLocation(location);
   })();
  });

  let valor = 'waiting...';
  if(errorMessage) {
    valor = errorMessage;
  }else if(location){
    valor = JSON.stringify(location);
  }

  reporte = JSON.parse(valor);
  console.log(valor);

  return (
    <View style={styles.container}>
      <Text style={styles.latitud}></Text>
      <Text style={styles.longitud}></Text>
      <Text style={styles.velocidad}></Text>
      <Text style={styles.direccion}></Text>
      <Text style={styles.ciudad}></Text>
      <Text style={styles.calle}></Text>
      <Text style={styles.heading2}>{errorMessage}</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1
  },
  mapView: {
    height: 338,
    width: 657,
    marginLeft: -108
  },
  latitud: {
    fontFamily: "roboto-regular",
    color: "#121212",
    marginTop: 64,
    marginLeft: 45
  },
  longitud: {
    fontFamily: "roboto-regular",
    color: "#121212",
    marginLeft: 45
  },
  velocidad: {
    fontFamily: "roboto-regular",
    color: "#121212",
    marginTop: 26,
    marginLeft: 45
  },
  direccion: {
    fontFamily: "roboto-regular",
    color: "#121212",
    marginTop: -38,
    marginLeft: 45
  },
  ciudad: {
    fontFamily: "roboto-regular",
    color: "#121212",
    fontSize: 40,
    marginTop: 58,
    marginLeft: 88
  },
  calle: {
    fontFamily: "roboto-regular",
    color: "#121212",
    fontSize: 25,
    marginLeft: 131
  }, 
    heading2:{
    color:"#fff",
    margin:5,
    fontWeight:"bold",
    fontSize:15
  },
});

export default Untitled1;

The data i recieve from my phone is presented like this.


Object {
   "coords": Object {
      "accuracy": 15.28600025177002,
       "altitude": 2233,
       "heading": 0,
       "latitude": -------,
       "longitude": ------,
       "speed": 0,
      },
    "mocked": false,
    "timestamp": 1592163692035,
        }

And what I did is to access the data this way: valor.coords and this gives me the next object:


Object {
    "accuracy": 14.409000396728516,
    "altitude": 2233,
    "heading": 80.9710693359375,
    "latitude": -------,
    "longitude": -------,
    "speed": 0.003523211693391204,
  }

I realized that this object has a trailing comma, so is invalid, so I proceeded to stringify it and get a valid JSON so i could do a JSON.parse(), but everytime i try this error comes out.


SyntaxError: SyntaxError: JSON Parse error: Unexpected identifier "waiting"

I don't really know how to proceed to with this one, so if you guys could help me, I would be more than grateful with you.

Upvotes: 0

Views: 7281

Answers (2)

Sennen Randika
Sennen Randika

Reputation: 1646

The problem is in here.

let valor = 'waiting...';

if(errorMessage) {
  valor = errorMessage;
}else if(location){
  valor = JSON.stringify(location);
}

reporte = JSON.parse(valor);
console.log(valor);

One is, you parse waiting... to JSON.parse() which will result you in this error.

To set the location, it takes very little time and the above code snippet is running before the location is set. This is due to very little difference of milliseconds.

So, please put the above code into a useEffect and listen to the location changes. Like this,

useEffect(() => {
    let valor = 'waiting...';
    let reporte = null;

    if (errorMessage) {
      valor = errorMessage;
    }
    else if (location) {
      valor = JSON.stringify(location); // If this is already stringyfied, no need to stringify it again.
      reporte = JSON.parse(valor);
    }

    console.log(valor);
  }, [location]);

So, your whole file will be as follows.

import React, { useEffect, useState } from 'react';
import { StyleSheet, View, Text, TouchableOpacity } from 'react-native';
import MapView, { Marker } from 'react-native-maps';

import * as Location from 'expo-location';
import * as Permissions from 'expo-permissions';

const Untitled1 = (props) => {
  const [errorMessage, setError] = useState(null);
  const [location, setLocation] = useState(null);

  useEffect(() => {
    (async () => {
      let { status } = await Permissions.askAsync(Permissions.LOCATION);
      if (status !== 'granted') {
        setError({
          errorMessage: 'Ubication service was denied',
        });
      }
      let location = await Location.getCurrentPositionAsync({
        accuracy: Location.Accuracy.Highest,
      });
      setLocation(location);
    })();
  }, []);

  useEffect(() => {
    let valor = 'waiting...';
    let reporte = null;

    if (errorMessage) {
      valor = errorMessage;
    }
    else if (location) {
      valor = JSON.stringify(location); // If this is already stringyfied, no need to stringify it again.
      reporte = JSON.parse(valor);
    }

    console.log(valor);
  }, [location]);

  return (
    <View style={styles.container}>
      <Text style={styles.latitud}></Text>
      <Text style={styles.longitud}></Text>
      <Text style={styles.velocidad}></Text>
      <Text style={styles.direccion}></Text>
      <Text style={styles.ciudad}></Text>
      <Text style={styles.calle}></Text>
      <Text style={styles.heading2}>{errorMessage}</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  mapView: {
    height: 338,
    width: 657,
    marginLeft: -108,
  },
  latitud: {
    fontFamily: 'roboto-regular',
    color: '#121212',
    marginTop: 64,
    marginLeft: 45,
  },
  longitud: {
    fontFamily: 'roboto-regular',
    color: '#121212',
    marginLeft: 45,
  },
  velocidad: {
    fontFamily: 'roboto-regular',
    color: '#121212',
    marginTop: 26,
    marginLeft: 45,
  },
  direccion: {
    fontFamily: 'roboto-regular',
    color: '#121212',
    marginTop: -38,
    marginLeft: 45,
  },
  ciudad: {
    fontFamily: 'roboto-regular',
    color: '#121212',
    fontSize: 40,
    marginTop: 58,
    marginLeft: 88,
  },
  calle: {
    fontFamily: 'roboto-regular',
    color: '#121212',
    fontSize: 25,
    marginLeft: 131,
  },
  heading2: {
    color: '#fff',
    margin: 5,
    fontWeight: 'bold',
    fontSize: 15,
  },
});

export default Untitled1;

Upvotes: 1

Porzio Jonathan
Porzio Jonathan

Reputation: 563

First of all you should not use the same object when you got an error and the result of the request

SyntaxError: SyntaxError: JSON Parse error: Unexpected identifier "waiting"

This error seems to come from this, you are trying to parse but you got an error. Secondly result is already in a JSON format so stringify and parse is not necessary, can you please provide a code snippet ?

Upvotes: 0

Related Questions