Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to pass a value between methods in same class in Android

Tags:

I have tried passing a value between 2 methods by following different solutions on here, but passes null.

The code I am trying to pass:

private void getPrice() {

    DatabaseReference dbRequest = FirebaseDatabase.getInstance().getReference(Common
            .request_tbl).child(riderId).child("details"); // "Requests"
    dbRequest.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot child : dataSnapshot.getChildren()) {
                if (child.getKey().equals("price")) {
                    price = Double.valueOf(child.getValue().toString());
                    Log.d(TAG, "getPrice: price = " + price);
                }
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {}
    });
}

Where I am trying to pass the value "price" to:

private void recordData(String riderId) {

    getPrice();
    Log.d(TAG, "recordData: price = " + price);

    ...
}

The value of price in getPrice() is what it is supposed to be but when I print out the value in recordData(), the value = null

like image 237
LizG Avatar asked Jun 30 '18 00:06

LizG


2 Answers

Answering your question in the comments: you don't have to pass the parameters inside the brackets, because you are setting up a callback.

But your problem comes from the precedence of methods. The value is not there yet when you call recordData.

The scenario is, in recordData you execute the line getPrice(), but the execution doesn't wait for getPrice() to finish because it's a callback, and the value will be returned as soon as it's retrieved, which can be long after. In order to prove it, you can look at your log. The chances are that this log:

Log.d(TAG, "recordData: price = " + price);

will be before this one:

Log.d(TAG, "getPrice: price = " + price);

So your best bet is to either execute recordData when you know exactly that the value is ready, or call it inside onDataChange.

like image 60
Suleyman Avatar answered Sep 28 '22 17:09

Suleyman


Use the callback as part of the getter

private void getPrice(ValueEventListener listener) {
    DatabaseReference dbRequest = FirebaseDatabase.getInstance().getReference(Common
            .request_tbl).child(riderId).child("details"); // "Requests"
    dbRequest.addValueEventListener(listener);
}

call it

getPrice(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for (DataSnapshot child : dataSnapshot.getChildren()) {
            if (child.getKey().equals("price")) {
                price = Double.valueOf(child.getValue().toString());
                Log.d(TAG, "getPrice: price = " + price);
                // Call a separate function that actually needs the price here
            }
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
       // Don't ignore your errors!
    }
);
// Note: price will still be null here
like image 31
OneCricketeer Avatar answered Sep 28 '22 19:09

OneCricketeer