Nxt3
Nxt3

Reputation: 2071

Get GsonConverterFactory to parse certain fields?

Given the following JSON response:

{
    "status":true,
    "doc":[
        {
            "_id":"9374",
            "t_id":"5678",
            "name":"Do calculus homework",
            "description":"Finish all assigned homework from chapters 1 and 2",
            "category":"test",
            "indexInList":0,
            "priority":3,
            "dateDue":1477291500000,
            "user":"def",
            "status":"ARCHIVED",
            "__v":0,
            "subtasks":[
                {
                    "name":"Finish Chapter 1 - Derivatives",
                    "isCompleted":false
                },
                {
                    "name":"Finish Chapter 1 - Integrals",
                    "isCompleted":false
                },
                {
                    "name":"Finish Chapter 2 - Graphing",
                    "isCompleted":false
                }
            ]
        },
        {
            "_id":"429808",
            "t_id":"1234",
            "name":"Write machine learning essay",
            "description":"Write essay on Bayesian networks",
            "category":"test",
            "indexInList":1,
            "priority":3,
            "dateDue":1477291500000,
            "user":"abc",
            "status":"ARCHIVED",
            "__v":0,
            "subtasks":[
                {
                    "name":"Write introduction",
                    "isCompleted":false
                },
                {
                    "name":"Write body",
                    "isCompleted":false
                },
                {
                    "name":"Write Conclusion",
                    "isCompleted":false
                }
            ]
        }
    ]
}

I'm using this in conjunction with Retrofit2. My Service class looks something like this:

private HavocService(String baseUrl) {
        //So network calls are async
        RxJavaCallAdapterFactory rxAdapter = RxJavaCallAdapterFactory.createWithScheduler(Schedulers.io());

        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();

        final Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .client(client)
                .addCallAdapterFactory(rxAdapter)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        mHavocApi = retrofit.create(HavocAPI.class);
    }

and I'm actually handling getting that data in an rx task:

rxHelper.manageSubscription(HavocService.getInstance().getHavocAPI().getAllTasks(userId)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .compose(RxTiPresenterUtils.deliverLatestToView(this))
                .subscribe(mListOfTasks -> {
                    this.mListOfTasks = mListOfTasks;
                    getView().setTaskList(mListOfTasks);
                }, throwable -> {
                    LogUtil.e("Error with something.");
                })
        );

How do I tell my GSONConverterFactory to start parsing at the "doc" array? I don't really care about the first "status" field.

I ask because I'm getting the following error: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $. I'm pretty sure it's because GSON is trying to parse the first item and not getting to the "doc" array.

I appreciate any and all help!

Edit

Here is the HavocAPI (I'm only concerned about the getAllTasks() working right now.)

public interface HavocAPI {

        /**
         * Creates a new Task
         *
         * @return status of whether or not the transaction was successful and the task that was created
         */
        @Headers({"Accept: application/json", "Content-Type: application/json"})
        @POST("task/create/")
        Observable<List<Object>> createNewTask();

        /**
         * Deletes a specified Task using the taskId
         *
         * @param taskID of the task
         * @return status of transaction
         */
        @Headers({"Accept: application/json", "Content-Type: application/json"})
        @POST("task/delete/{task_id}/")
        Observable<Boolean> deleteTask(@Path("task_id") String taskID);

        /**
         * Updates a Task
         *
         * @return status of whether or not the transaction was successful and the task that was updated
         */
        @Headers({"Accept: application/json", "Content-Type: application/json"})
        @POST("task/update/")
        Observable<List<Object>> updateTask();

        /**
         * Gets all Tasks by a specified User
         *
         * @param userId of the user
         * @return list of all Tasks from the specified User
         */
        @Headers({"Accept: application/json", "Content-Type: application/json"})
        @GET("task/read/{user_id}/")
        Observable<List<Task>> getAllTasks(@Path("user_id") String userId);
    }

Upvotes: 0

Views: 415

Answers (1)

Abtin Gramian
Abtin Gramian

Reputation: 1780

The return type for the getAllTasks() method is incorrect. You need to create a new model representing the actual response format then access the task list through it.

class GetTasksResponse {
    bool status;
    @SerializedName("doc")
    List<Task> tasks;

    public List<Task> getTasks() {
        return tasks;
    }
}

Upvotes: 3

Related Questions