java – LiveData object goes null when passing it to ViewModel

I am making a project in Android studio where I get a List of objects from an API. Unfortunately, I have a problem with LiveData as it passess null from the repository to a ViewModel.

In the repository class it calls the API, parses the response and sets the value of LiveData:

    private final Dao dao;
    private static Repository instance;
    private final MutableLiveData<Fare> searchedFare;
    @Nullable
    private final MutableLiveData<List<Arrival>> searchedArrivals;

    private Repository(){
        dao = Dao.getInstance();
        searchedFare = new MutableLiveData<>();
        searchedArrivals = new MutableLiveData<>() ;

    }

    public static Repository getInstance(){
        if(instance==null){
            instance = new Repository();
        }
        return instance;
    }

    public MutableLiveData<List<Arrival>> getReceivedArrivals() {return searchedArrivals;}

    public void searchForArrivals(){
        TaxiApiMock taxiApiMock = ServiceGenerator.getTaxiApi();
        Call<List<Arrival>> call = taxiApiMock.getArrivals();
        call.enqueue(new Callback<List<Arrival>>() {
            @EverythingIsNonNull
            @Override
            public void onResponse(Call<List<Arrival>> call, Response<List<Arrival>> response) {
                if(response.isSuccessful())
                    searchedArrivals.setValue(response.body());
                Log.d("Retrofit","Messages successfully received!");
                Log.d("Retrofit", new Gson().toJson(response.body()));
                Log.d("Retrofit", "Message successfully parsed!");

                for (Arrival arrival: Objects.requireNonNull(searchedArrivals.getValue())) {
                    Log.d("Retrofit",arrival.toString());
                }
                Log.d("Retrofit", searchedArrivals.toString());
                Log.d("Retrofit", searchedArrivals.getValue().toString());
                Log.d("Retrofit", searchedArrivals.getValue().get(0).toString());

            }

            @EverythingIsNonNull
            @Override
            public void onFailure(Call<List<Arrival>> call, Throwable t) {
                Log.i("Retrofit","Something went wrong! :(");
            }
        });
    }

And everything goes as planned until I pass it to the ViewModel, where I get a NullPointer.

public void searchForArrival(){
        repository.searchForArrivals();
        Log.d("VM", repository.getReceivedArrivals().toString());
        Log.d("VM", repository.getReceivedArrivals().getValue().toString());
        if(mArrival.getValue()==null)
            Log.d("VM", "list is null");
        else{
        Log.d("Retrofit", mArrival.toString());
        Log.d("Retrofit", mArrival.getValue().toString());
        Log.d("Retrofit", mArrival.getValue().get(0).toString());}
    }

Here is how the logcat looks when printing in ViewModel class:

    java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference
        at com.example.taxiapp.ui.timetable.TimetableViewModel.searchForArrival(TimetableViewModel.java:47)
        at com.example.taxiapp.ui.timetable.TimetableFragment$1.onClick(TimetableFragment.java:37)...

And here how it looks (perfectly) in Repository class:

2022-05-16 01:47:56.901 10487-10487/com.example.taxiapp D/Retrofit: Messages successfully received!
2022-05-16 01:47:56.905 10487-10487/com.example.taxiapp D/Retrofit: [{"cancelled":false,"date":"14.05.22","messages":"Lorem Ipsum","name":"Bus 100","origin":"CPH-Lufthavn","rtTrack":0,"stop":"Horsens","time":"21:37","track":0,"type":"IC"},{"cancelled":false,"date":"14.05.22","messages":"Lorem Ipsum","name":"Bus 100","origin":"Esbjerg","rtTrack":0,"stop":"Horsens","time":"23:37","track":0,"type":"REG"},{"cancelled":false,"date":"14.05.22","messages":"Lorem Ipsum","name":"Bus 100","origin":"Randers","rtTrack":0,"stop":"Horsens","time":"22:37","track":0,"type":"IC"}]
2022-05-16 01:47:56.906 10487-10487/com.example.taxiapp D/Retrofit: Message successfully parsed!
2022-05-16 01:47:56.906 10487-10487/com.example.taxiapp D/Retrofit: Arrival{name="Bus 100", type="IC", stop='Horsens', time="21:37", date="14.05.22", track=0, realTime="null", realDate="null", realTrack=0, origin='CPH-Lufthavn', cancelled=false, messages="Lorem Ipsum"}
2022-05-16 01:47:56.906 10487-10487/com.example.taxiapp D/Retrofit: Arrival{name="Bus 100", type="REG", stop='Horsens', time="23:37", date="14.05.22", track=0, realTime="null", realDate="null", realTrack=0, origin='Esbjerg', cancelled=false, messages="Lorem Ipsum"}
2022-05-16 01:47:56.906 10487-10487/com.example.taxiapp D/Retrofit: Arrival{name="Bus 100", type="IC", stop='Horsens', time="22:37", date="14.05.22", track=0, realTime="null", realDate="null", realTrack=0, origin='Randers', cancelled=false, messages="Lorem Ipsum"}
2022-05-16 01:47:56.906 10487-10487/com.example.taxiapp D/Retrofit: androidx.lifecycle.MutableLiveData@49b4d1d
2022-05-16 01:47:56.907 10487-10487/com.example.taxiapp D/Retrofit: [Arrival{name="Bus 100", type="IC", stop='Horsens', time="21:37", date="14.05.22", track=0, realTime="null", realDate="null", realTrack=0, origin='CPH-Lufthavn', cancelled=false, messages="Lorem Ipsum"}, Arrival{name="Bus 100", type="REG", stop='Horsens', time="23:37", date="14.05.22", track=0, realTime="null", realDate="null", realTrack=0, origin='Esbjerg', cancelled=false, messages="Lorem Ipsum"}, Arrival{name="Bus 100", type="IC", stop='Horsens', time="22:37", date="14.05.22", track=0, realTime="null", realDate="null", realTrack=0, origin='Randers', cancelled=false, messages="Lorem Ipsum"}]
2022-05-16 01:47:56.907 10487-10487/com.example.taxiapp D/Retrofit: Arrival{name="Bus 100", type="IC", stop='Horsens', time="21:37", date="14.05.22", track=0, realTime="null", realDate="null", realTrack=0, origin='CPH-Lufthavn', cancelled=false, messages="Lorem Ipsum"}

Leave a Comment