kamikat / moshi-jsonapi

JSON API v1.0 Specification in Moshi.
MIT License
156 stars 34 forks source link

How to get list of resources with different types? #5

Closed thanh-taro closed 8 years ago

thanh-taro commented 8 years ago

I have a json like this:

{
  "jsonapi": {
    "version": "1.0"
  },
  "meta": {
    "isNew": true
  },
  "data": [
    {
      "id": 4,
      "type": "user",
      "attributes": {
        "facebookId": "facebookId",
        "email": "email.abc@gmail.com",
        "name": "Lê Uyên Nguyễn",
        "avatar": "users/avatars/8c0f5fc9e15003b1692d564b5a009b00.jpg",
        "updated_at": "2016-08-22 23:30:11",
        "created_at": "2016-08-22 23:30:11",
        "loc": null
      }
    },
    {
      "id": "cfc60085d96d2bdb46ac719586fe8e28",
      "type": "accessToken",
      "attributes": {
        "tokenType": "Bearer",
        "value": "token-abc"
      }
    }
  ]
}

How can I get 2 resources (user and accessToken) in the array data?

kamikat commented 8 years ago

Just use Resource[]

thanh-taro commented 8 years ago

Thanks for a fast reply. I'll try it.

trivien0 commented 8 years ago

Resource[] resources = moshi.adapter(Resource[].class).fromJson(response); How to fix error: No JsonAdapter for interface com.android.tools.fd.runtime.IncrementalChange annotated []?

kamikat commented 8 years ago

@zzztrivienzzz You should add a custom adapter for IncrementalChange if you'd like to serialize/deserialize it with moshi. Or just declare the field with transient modifier to ignore it.

thanh-taro commented 8 years ago

I want to use transient but I've tried many times. But it didn't work. Could you please take some time and give me an example for my json above?

kamikat commented 8 years ago

Are you using the library directly or use a retrofit?

thanh-taro commented 8 years ago

I'm using it directly.

kamikat commented 8 years ago

Hmm... I've tested your JSON against the library and everything just works fine https://gist.github.com/kamikat/24b08d3bfcb7ce964dd999c49a13ccaf

Is there any stacktrace about the problem?

thanh-taro commented 8 years ago

I got the error:

com.squareup.moshi.JsonDataException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at path $

Here is the stacktrace:

FATAL EXCEPTION: main
Process: com.e4bros.thodia, PID: 10070
com.squareup.moshi.JsonDataException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at path $
    at com.squareup.moshi.JsonReader.beginArray(JsonReader.java:346)
    at com.squareup.moshi.ArrayJsonAdapter.fromJson(ArrayJsonAdapter.java:53)
    at com.squareup.moshi.JsonAdapter$1.fromJson(JsonAdapter.java:68)
    at com.squareup.moshi.JsonAdapter.fromJson(JsonAdapter.java:33)
    at com.squareup.moshi.JsonAdapter.fromJson(JsonAdapter.java:37)
    at com.e4bros.thodia.signin.SignInPresenter$6.onResponse(SignInPresenter.java:255)
    at com.e4bros.thodia.signin.SignInPresenter$6.onResponse(SignInPresenter.java:213)
    at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:67)
    at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:30)
    at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:135)
    at android.app.ActivityThread.main(ActivityThread.java:5254)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

This is my code:

String json = "{" +
                       "  \"jsonapi\": {" +
                       "    \"version\": \"1.0\"" +
                       "  }," +
                       "  \"meta\": {" +
                       "    \"isNew\": true" +
                       "  }," +
                       "  \"data\": [" +
                       "    {" +
                       "      \"id\": 4," +
                       "      \"type\": \"user\"," +
                       "      \"attributes\": {" +
                       "        \"facebookId\": \"facebookId\"," +
                       "        \"email\": \"email.abc@gmail.com\"," +
                       "        \"name\": \"Lê Uyên Nguyễn\"," +
                       "        \"avatar\": \"users/avatars/8c0f5fc9e15003b1692d564b5a009b00.jpg\"," +
                       "        \"updated_at\": \"2016-08-22 23:30:11\"," +
                       "        \"created_at\": \"2016-08-22 23:30:11\"," +
                       "        \"loc\": null" +
                       "      }" +
                       "    }," +
                       "    {" +
                       "      \"id\": \"cfc60085d96d2bdb46ac719586fe8e28\"," +
                       "      \"type\": \"accessToken\"," +
                       "      \"attributes\": {" +
                       "        \"tokenType\": \"Bearer\"," +
                       "        \"value\": \"token-abc\"" +
                       "      }" +
                       "    }" +
                       "  ]" +
                       "}";
Moshi moshi = new Moshi.Builder()
                                .add(ResourceAdapterFactory.builder()
                                        .add(AccessToken.class)
                                        .add(User.class)
                                        .build()).build();
Resource[] data = (Resource[]) moshi.adapter(Types.arrayOf(Resource.class)).fromJson(json);
kamikat commented 8 years ago

Oh... I'm sorry.

Resource[] data = (Resource[]) moshi.adapter(Types.arrayOf(Resource.class)).fromJson(JSON);

The line comes from a test case for retrofit use which fails before 2.0.10 release. It should be ok to be replaced with following line:

Resource[] data = moshi.adapter(Resource[].class).fromJson(JSON);
thanh-taro commented 8 years ago

I figured it out. Just change Types.arrayOf(Resource.class) to Resource[].class and it works.

thanh-taro commented 8 years ago

:dancer: Just figured it out at the same time.

kamikat commented 8 years ago

@thanh-taro would you mind if I add the snippet as a part of the library's test case?

thanh-taro commented 8 years ago

Yeah. You can use it. No problems.