dacscan3669
dacscan3669

Reputation: 761

Java How to return the variable outside the listener

I am calling the method getRecipesFromDB of Recipe class from MainActivity class listed below. getRecipesFromDB retrieves the data from Firebase DB and populated recipeList. I am able to print the content successfully when the used within the scope of EventListener. But when the recipeList is returned to the main class, it returns null.

Question: How do we return recipeList to the MainActivity class? currently it returns null.

Code is below:

 public class Recipe {

  public String title;
  public String description;
  public String image;
  public String url;
  public String dietLabel;

  public Recipe () {
  }

  public String getTitle() {
    return title;
  }
 public String getDescription() {
    return description;
  }
 public String getImageUrl() {
    return image;
  }
 public String getInstructionUrl() {
    return url;
  }
 public String getLabel() { 
    return dietLabel; 
  }

public static ArrayList<Recipe> getRecipesFromDB(){
   final ArrayList<Recipe> recipeList = new ArrayList<>();
   final DatabaseReference mDatabase;
   final Recipe recipe = new Recipe();


mDatabase = FirebaseDatabase.getInstance().getReference("recipes");

mDatabase.addValueEventListener(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot snapshot) {
    System.out.println("There are " + snapshot.getChildrenCount() + " recipes");

    for (DataSnapshot postSnapshot : snapshot.getChildren()) {
      Recipe post = postSnapshot.getValue(Recipe.class);

      recipe.title = post.getTitle();
      recipe.description = post.getDescription();
      recipe.image = post.getImageUrl();
      recipe.url = post.getInstructionUrl();
      recipe.dietLabel = post.getLabel();

      recipeList.add(recipe);
    }
 }

  @Override
  public void onCancelled(DatabaseError databaseError) {
    System.out.println("The read failed: " + databaseError.getMessage());
  }
});

return recipeList; //This return null
/*I am trying to return as above to another class where it is called but this returns null. What needs to be done for this to return the recipeList which has been set inside the listener?*/
  }
}

/* Below is the class where the Recipe.getRecipesFromDB is called */

public class MainActivity extends AppCompatActivity {
  private ListView mListView;

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  mListView = (ListView) findViewById(R.id.recipe_list_view);

  final ArrayList<Recipe> recipeList = Recipe.getRecipesFromDB();

  RecipeAdapter adapter = new RecipeAdapter(this, recipeList);
  mListView.setAdapter(adapter);
 }
}

Upvotes: 0

Views: 1768

Answers (1)

Shaishav
Shaishav

Reputation: 5312

One of the ways: You can pass an interface from your MainActivity to your listener class and then call the method with data in your listener when you receive it. Implement the interface in MainActivity.It can be something like:

public interface DataListener {
    void newDataReceived(ArrayList<Recipe> recipeList);
}

Edit: Usage example:

You need to have your listener method defined as:

public static ArrayList<Recipe> getRecipesFromDB(DataListener dataListener){
   final ArrayList<Recipe> recipeList = new ArrayList<>();
   final DatabaseReference mDatabase;
   final Recipe recipe = new Recipe();


  mDatabase = FirebaseDatabase.getInstance().getReference("recipes");

 mDatabase.addValueEventListener(new ValueEventListener() {
  @Override 
  public void onDataChange(DataSnapshot snapshot) {
    System.out.println("There are " + snapshot.getChildrenCount() + " recipes");

    for (DataSnapshot postSnapshot : snapshot.getChildren()) {
      Recipe post = postSnapshot.getValue(Recipe.class);

      recipe.title = post.getTitle();
      recipe.description = post.getDescription();
      recipe.image = post.getImageUrl();
      recipe.url = post.getInstructionUrl();
      recipe.dietLabel = post.getLabel();

      recipeList.add(recipe);
    } 

    // Transaction complete, sending to listener
    dataListener.newDataReceived(recipeList);
 } 

You will need to call this method with an instance of DataListener. You can call this either anonymously:

getRecipesFromDB(new DataListener() {
    @Overrride
    public void newDataReceived(recipeList) {
         // Data will be received here
    }
});

Or, you can have your MainActivity implement the method:

public class MainActvity implements DataListener {
    ...
    @Overrride
    public void newDataReceived(recipeList) {
         // Data will be received here
    }
    ...
}

Upvotes: 2

Related Questions