Reputation: 31
I am creating a project in which i am using themoviedb api to fetch data. For this I am using MVVM architecture. From MovieListFragment , I want to pass category such as popular, top_rated to MovieViewModel for filtering the movies accordingly , but there i am getting null value.
Here is MovieListFragment class :-
public class MovieListFragment extends Fragment {
private MovieViewModel movieViewModel;
private static final String BASE_URL = "https://api.themoviedb.org";
private static final String API_KEY = "API_KEY";
private String category;
private GridView gridView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_movie_list, container, false);
gridView = rootView.findViewById(R.id.images_grid_view);
movieViewModel = ViewModelProviders.of(this).get(MovieViewModel.class);
movieViewModel.setCategory(category); // from here i am passing value
movieViewModel.getMoviesRepository().observe(getActivity(), new Observer<MovieResults>() { // error line no :- 76
@Override
public void onChanged(MovieResults movieResults) {
final List<MovieResults.ResultsBean> listOfMovies = movieResults.getResults(); // error line no :- 79
MovieListAdapter mAdapter = new MovieListAdapter(getContext(), listOfMovies);
gridView.setAdapter(mAdapter);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mCallback.onImageSelected(position, listOfMovies);
}
});
}
});
return rootView;
}
public void setCategory(String category) {
this.category = category;
}
}
Here is MovieViewModel class :-
public class MovieViewModel extends AndroidViewModel {
private String category;
private static final String API_KEY = "api_key";
private MovieRepository repository;
private MutableLiveData<MovieResults> listOfMovies;
public MovieViewModel(@NonNull Application application) {
super(application);
Log.d("MovieViewModel", category); // but here i am getting null value
listOfMovies = repository.getListOfMovies(category, API_KEY);
}
public MutableLiveData<MovieResults> getMoviesRepository() {
return listOfMovies;
}
public void setCategory(String category) {
this.category = category;
}
}
I am getting error like this :-
java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.List com.mountblue.moviesapp.entity.MovieResults.getResults()' on a null object reference
at com.mountblue.moviesapp.fragment.MovieListFragment$2.onChanged(MovieListFragment.java:79)
at com.mountblue.moviesapp.fragment.MovieListFragment$2.onChanged(MovieListFragment.java:76)
Upvotes: 3
Views: 14733
Reputation: 76
In MovieListFragment class:
First delete this line: movieViewModel.setCategory(category);
And pass "category" here: movieViewModel.getMoviesRepository(category)
like code below:
movieViewModel.getMoviesRepository(category).observe(getActivity(), new Observer<MovieResults>() { // error line no :- 76
@Override
public void onChanged(MovieResults movieResults) {
final List<MovieResults.ResultsBean> listOfMovies = movieResults.getResults(); // error line no :- 79
MovieListAdapter mAdapter = new MovieListAdapter(getContext(), listOfMovies);
gridView.setAdapter(mAdapter);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mCallback.onImageSelected(position, listOfMovies);
}
});
}
});
In MovieViewModel class:
Move this line inside getMoviesRepository(String category) listOfMovies = repository.getListOfMovies(category, API_KEY);
And just remove category variable and setCategory()
method from MovieViewModel
class like this:
public class MovieViewModel extends AndroidViewModel {
private static final String API_KEY = "api_key";
private MovieRepository repository;
private MutableLiveData<MovieResults> listOfMovies;
public MovieViewModel(@NonNull Application application) {
super(application);
}
public MutableLiveData<MovieResults> getMoviesRepository(String category) {
Log.d("MovieViewModel", category); // but here i am getting null value
listOfMovies = repository.getListOfMovies(category, API_KEY);
return listOfMovies;
}
}
Upvotes: 0
Reputation: 72
Since the Category is read by the constructor of MovieViewModel before the setter, it is always null.
What about category as method arguments?
public class MovieViewModel extends AndroidViewModel {
private static final String API_KEY = "api_key";
private MovieRepository repository;
private MutableLiveData<MovieResults> listOfMovies = new MutableLiveData<MovieResults>();
public MovieViewModel(@NonNull Application application) {
super(application);
}
public MutableLiveData<MovieResults> getMoviesRepository(category) {
loadData(category);
return listOfMovies;
}
private void loadData(category) {
// Do an asynchronous operation to fetch MovieResults.
repository.getListOfMovies(category, API_KEY);
...
// Receive asynchronous result in callback
// Post the result after getting the asynchronous result.
listOfMovies.postValue(response)
}
}
For a more detailed implementation, need a repository class.
Documents: https://developer.android.com/topic/libraries/architecture/viewmodel
Upvotes: 0
Reputation: 108
If you are getting null
value for the string category
in line movieViewModel.setCategory(category);
, it means the field category
of MovieListFragment
is null.
Try checking if you have invoked the setCategory(String category)
method on the fragment
.
If that's not the case, please elaborate on the error. E.g. on which line it occurs etc.
Upvotes: 0