facebook / react-native

A framework for building native applications using React

Home Page:https://reactnative.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

put Long value to WritableMap

mauron85 opened this issue · comments

Thank you guys for great work on react-native for Android.

Issue Description

I believe following could be considered as bug. Currently it is impossible to put Long value into WritableMap. Typical usage of Long value is android geolocation time (timestamp). It could not be be converted to int, because it is larger than java Integer.MAX_VALUE.

Steps to Reproduce / Code Snippets

  @ReactMethod
  public void getLocations(Callback success, Callback error) {
    WritableArray locationsArray = Arguments.createArray();
    LocationDAO dao = DAOFactory.createLocationDAO(getContext());
    try {
      Collection<Location> locations = dao.getAllLocations();
      for (Location location : locations) {
        WritableMap out = Arguments.createMap();
        out.putInt("time", Convert.safeLongToInt(location.getTime())); // time cannot be converted safely to int
        out.putDouble("latitude", location.getLatitude());
        out.putDouble("longitude", location.getLongitude());
        out.putDouble("accuracy", location.getAccuracy());
        out.putDouble("speed", location.getSpeed());
        out.putDouble("altitude", location.getAltitude());
        out.putDouble("bearing", location.getBearing());

        locationsArray.pushMap(out);
      }
      success.invoke(locationsArray);
    } catch (Exception e) {
      Log.e(TAG, "Getting all locations failed: " + e.getMessage());
      error.invoke("Converting locations to JSON failed.");
    }
  }

Expected Results

WritableMap should have method putLong.

Additional Information

  • React Native version: 0.29
  • Platform(s) (iOS, Android, or both?): Android
  • Operating System (macOS, Linux, or Windows?): macOS, Linux, Windows

Why don't you put it as a double then? JS doesn't have multiple numeric types, whether you'd put a long or double on the native side would be irrelevant for JS.

There are multiple ways to convert a long into a double. You can either try to cast it with double time = location.getTime(); or make use of chaining https://docs.oracle.com/javase/7/docs/api/java/lang/Long.html#valueOf(long)
https://docs.oracle.com/javase/7/docs/api/java/lang/Long.html#doubleValue()

As a reply to "I believe following could be considered as bug.", it's surely not a bug as there's no method that causes a failure or anything, it's more of an inconvenience. It was a convenience for me as well recently, so I simply did the casting above. If it's too much a trouble for you, please send a PR and I'm sure a Facebook employee would consider it.

Ok I exaggerated bit with bug definition just to get attention to this. :-) Sorry for that. Also thank you for suggestion with using double. Will try that. Anyway I'll keep this issue open if you don't mind. Maybe I can take look on RN internals and implement that.

@hey99xx brings up a great point. JavaScript does not have longs and a PR for this issue is going to cause subtle bugs. You must either use a 64-bit double, 53-bit int (Java's 32-bit ints are OK), or string. This is a limitation of JavaScript, not React Native, so I'm going to close this out.