Home > Software design >  RecyclerView not showing data fetched from API
RecyclerView not showing data fetched from API

Time:08-24

Im creating an app that shows user recipe based on ingredient they have using SpoonAcular API The app fetched the ingredient user currently have on Firebase Realtime Database and using the data to fetch the recipe. I've created all the adapter needed to fetch the data but the app not showing the recyclerView as its should. Here's my code

RequestManager.java

public class RequestManager {

    Context context;
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://api.spoonacular.com/")
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    public RequestManager(Context context){
        this.context = context;
    }

    public void getRecipeByIngredient(RecipeByIngredientListener listener, List <String> IngredientList){
        CallRecipeByIngredient callRecipeByIngredient = retrofit.create(CallRecipeByIngredient.class);


        Call <List<RecipeIngredResponse>> call = callRecipeByIngredient.callRecipeByIngredient(context.getString(R.string.API), IngredientList, "20");
        call.enqueue(new Callback<List<RecipeIngredResponse>>() {
            @Override
            public void onResponse(Call<List<RecipeIngredResponse>> call, Response<List<RecipeIngredResponse>> response) {
                if(!response.isSuccessful()){
                    listener.didError(response.message());
                    return;
                }
                listener.didFetch(response.body(), response.message());
            }

            @Override
            public void onFailure(Call<List<RecipeIngredResponse>> call, Throwable t) {
                listener.didError(t.getMessage());
            }
        });
    }

    private interface CallRecipeByIngredient{
        @GET("recipes/findByIngredients")
        Call<List<RecipeIngredResponse>> callRecipeByIngredient(
                @Query("apiKey") String apiKey,
                @Query("ingredients") List <String> Ingredient,
                @Query("number") String number
        );
    }
}

RecipeByIngredientListener

public interface RecipeByIngredientListener {
    void didFetch(List<RecipeIngredResponse> response, String message);
    void didError(String message);
}

RecipeByIngredientAdapter

public class RecipeByIngredientAdapter extends RecyclerView.Adapter<RecipeByIngredientViewHolder> {

    Context context;
    List<RecipeIngredResponse> list;

    public RecipeByIngredientAdapter(Context context, List<RecipeIngredResponse> list) {
        this.context = context;
        this.list = list;
    }

    @NonNull
    @Override
    public RecipeByIngredientViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new RecipeByIngredientViewHolder(LayoutInflater.from(context).inflate(R.layout.list_recipebyingred , parent, false));
    }

    @SuppressLint("SetTextI18n")
    @Override
    public void onBindViewHolder(@NonNull RecipeByIngredientViewHolder holder, int position) {
        holder.recipeName.setText(list.get(position).title);
        holder.missedIngred.setText(list.get(position).missedIngredientCount   " Missed Ingredient");
        holder.likes.setText(list.get(position).likes   " Likes");
        Picasso.get().load(list.get(position).image).into(holder.recipeImage);
    }

    @Override
    public int getItemCount() {
        return list.size();
    }
}

class RecipeByIngredientViewHolder extends RecyclerView.ViewHolder{

    ImageView recipeImage;
    TextView recipeName, missedIngred, likes;

    public RecipeByIngredientViewHolder(@NonNull View itemView) {
        super(itemView);

        recipeImage = itemView.findViewById(R.id.recipeImage);
        recipeName = itemView.findViewById(R.id.recipeName);
        missedIngred = itemView.findViewById(R.id.missedIngred);
        likes = itemView.findViewById(R.id.likes);
    }
}

Home.java (Fragment)

RandomRecipeAdapter randomRecipeAdapter;
RequestManager manager;
RecyclerView recyclerView, recyclerFromYourFridge;
RecipeByIngredientAdapter recipeByIngredientAdapter;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    // Inflate the layout for this fragment
    View v =  inflater.inflate(R.layout.fragment_home, container, false);

    manager = new RequestManager(getContext());
    manager.getRandomRecipe(randomRecipeResponseListener);

    recyclerFromYourFridge = (RecyclerView) v.findViewById(R.id.recyclerFromYourFridge);
    //get ingredient from database
    List<String> Ingredient =  new ArrayList<>();
    FirebaseAuth mAuth = FirebaseAuth.getInstance();
    String currentUser = mAuth.getCurrentUser().getUid();
    DatabaseReference reference = FirebaseDatabase.getInstance().getReference().child("Ingredient").child(currentUser);
    reference.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
        @Override
        public void onComplete(@NonNull Task<DataSnapshot> task) {
            if(task.isSuccessful()){
                for (DataSnapshot userSnapshot : task.getResult().getChildren()){
                    Ingredient.add(userSnapshot.getKey());
                }
            }
        }
    });

    manager.getRecipeByIngredient(recipeByIngredientListener , Ingredient);

    recyclerView = (RecyclerView) v.findViewById(R.id.randomRecipeRecycler);
    return v;

}

private final RecipeByIngredientListener recipeByIngredientListener = new RecipeByIngredientListener() {
    @Override
    public void didFetch(List<RecipeIngredResponse> response, String message) {

        recyclerFromYourFridge.setHasFixedSize(true);
        recyclerFromYourFridge.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
        recipeByIngredientAdapter = new RecipeByIngredientAdapter(getContext(), response);
        recyclerFromYourFridge.setAdapter(recipeByIngredientAdapter);
    }

    @Override
    public void didError(String message) {
        Toast.makeText(getContext(), message, Toast.LENGTH_SHORT).show();
    }
};

Pretty sure there's nothing wrong with the app fetching ingredient from Firebase cause i've tested it and the api capable to get recipe by using ArrayList. Is there anything wrong with this code?

CodePudding user response:

The issue is because calls to the Firebase database are asynchronous, if you call the value outside of addOnCompleteListener can be empty

Change the reference.get().addOnCompleteListener to:

reference.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
    @Override
    public void onComplete(@NonNull Task<DataSnapshot> task) {
        if(task.isSuccessful()){
            List<String> Ingredient =  new ArrayList<>();
            for (DataSnapshot userSnapshot : task.getResult().getChildren()){
                Ingredient.add(userSnapshot.getKey());
            }
            manager.getRecipeByIngredient(recipeByIngredientListener , Ingredient);
        }
    }
});
  • Related