LiveData.getValue() returns null with Room












14















Java POJO Object



public class Section {

@ColumnInfo(name="section_id")
public int mSectionId;

@ColumnInfo(name="section_name")
public String mSectionName;

public int getSectionId() {
return mSectionId;
}

public void setSectionId(int mSectionId) {
this.mSectionId = mSectionId;
}

public String getSectionName() {
return mSectionName;
}

public void setSectionName(String mSectionName) {
this.mSectionName = mSectionName;
}
}


My Query method



@Query("SELECT * FROM section")
LiveData<List<Section>> getAllSections();


Accessing DB



final LiveData<List<Section>> sections = mDb.sectionDAO().getAllSections();


On the next line I am checking sections.getValue() which is always giving me null although I have data in the DataBase and later I am getting the value in the onChanged() method.



sections.observe(this, new Observer<List<Section>>() {
@Override
public void onChanged(@Nullable List<Section> sections){

}
});


But when I omit LiveData from the query I am getting the data as expected.
Query Method:



@Query("SELECT * FROM section")
List<Section> getAllSections();


Accessing DB:



final List<Section> sections = mDb.sectionDAO().getAllSections();









share|improve this question


















  • 1





    But why you want to use sections.getValue(), while livedata are used to observe the data. May be when you are checking in next line, data is not set in livedata that's why it gives you null. In short if you don't want to use LiveData then just use it without LiveData.

    – Moinkhan
    Jun 8 '17 at 8:42






  • 2





    I want to use livedata...if sections.getValue() is null I have to call api for data and insert in into the database which will eventually call the onChange() method from where I will get the data. But Because of that null value if and getting data from both database and api.

    – CodeCameo
    Jun 8 '17 at 12:13











  • I'll just add that, it is helpful to know that onChanged is also called the first time the data is initialized/ready, so you don't have to do the initial data retrieval yourself.

    – Karuhanga
    Jul 1 '18 at 2:40











  • Exact same problem here. I too am checking if there is value in database, and if there is not then I have to call APIte get datat which then saves the data in Database. Still no solution for me. Android MVVM sucks !

    – zulkarnain shah
    Jul 26 '18 at 11:00
















14















Java POJO Object



public class Section {

@ColumnInfo(name="section_id")
public int mSectionId;

@ColumnInfo(name="section_name")
public String mSectionName;

public int getSectionId() {
return mSectionId;
}

public void setSectionId(int mSectionId) {
this.mSectionId = mSectionId;
}

public String getSectionName() {
return mSectionName;
}

public void setSectionName(String mSectionName) {
this.mSectionName = mSectionName;
}
}


My Query method



@Query("SELECT * FROM section")
LiveData<List<Section>> getAllSections();


Accessing DB



final LiveData<List<Section>> sections = mDb.sectionDAO().getAllSections();


On the next line I am checking sections.getValue() which is always giving me null although I have data in the DataBase and later I am getting the value in the onChanged() method.



sections.observe(this, new Observer<List<Section>>() {
@Override
public void onChanged(@Nullable List<Section> sections){

}
});


But when I omit LiveData from the query I am getting the data as expected.
Query Method:



@Query("SELECT * FROM section")
List<Section> getAllSections();


Accessing DB:



final List<Section> sections = mDb.sectionDAO().getAllSections();









share|improve this question


















  • 1





    But why you want to use sections.getValue(), while livedata are used to observe the data. May be when you are checking in next line, data is not set in livedata that's why it gives you null. In short if you don't want to use LiveData then just use it without LiveData.

    – Moinkhan
    Jun 8 '17 at 8:42






  • 2





    I want to use livedata...if sections.getValue() is null I have to call api for data and insert in into the database which will eventually call the onChange() method from where I will get the data. But Because of that null value if and getting data from both database and api.

    – CodeCameo
    Jun 8 '17 at 12:13











  • I'll just add that, it is helpful to know that onChanged is also called the first time the data is initialized/ready, so you don't have to do the initial data retrieval yourself.

    – Karuhanga
    Jul 1 '18 at 2:40











  • Exact same problem here. I too am checking if there is value in database, and if there is not then I have to call APIte get datat which then saves the data in Database. Still no solution for me. Android MVVM sucks !

    – zulkarnain shah
    Jul 26 '18 at 11:00














14












14








14


4






Java POJO Object



public class Section {

@ColumnInfo(name="section_id")
public int mSectionId;

@ColumnInfo(name="section_name")
public String mSectionName;

public int getSectionId() {
return mSectionId;
}

public void setSectionId(int mSectionId) {
this.mSectionId = mSectionId;
}

public String getSectionName() {
return mSectionName;
}

public void setSectionName(String mSectionName) {
this.mSectionName = mSectionName;
}
}


My Query method



@Query("SELECT * FROM section")
LiveData<List<Section>> getAllSections();


Accessing DB



final LiveData<List<Section>> sections = mDb.sectionDAO().getAllSections();


On the next line I am checking sections.getValue() which is always giving me null although I have data in the DataBase and later I am getting the value in the onChanged() method.



sections.observe(this, new Observer<List<Section>>() {
@Override
public void onChanged(@Nullable List<Section> sections){

}
});


But when I omit LiveData from the query I am getting the data as expected.
Query Method:



@Query("SELECT * FROM section")
List<Section> getAllSections();


Accessing DB:



final List<Section> sections = mDb.sectionDAO().getAllSections();









share|improve this question














Java POJO Object



public class Section {

@ColumnInfo(name="section_id")
public int mSectionId;

@ColumnInfo(name="section_name")
public String mSectionName;

public int getSectionId() {
return mSectionId;
}

public void setSectionId(int mSectionId) {
this.mSectionId = mSectionId;
}

public String getSectionName() {
return mSectionName;
}

public void setSectionName(String mSectionName) {
this.mSectionName = mSectionName;
}
}


My Query method



@Query("SELECT * FROM section")
LiveData<List<Section>> getAllSections();


Accessing DB



final LiveData<List<Section>> sections = mDb.sectionDAO().getAllSections();


On the next line I am checking sections.getValue() which is always giving me null although I have data in the DataBase and later I am getting the value in the onChanged() method.



sections.observe(this, new Observer<List<Section>>() {
@Override
public void onChanged(@Nullable List<Section> sections){

}
});


But when I omit LiveData from the query I am getting the data as expected.
Query Method:



@Query("SELECT * FROM section")
List<Section> getAllSections();


Accessing DB:



final List<Section> sections = mDb.sectionDAO().getAllSections();






android android-room android-architecture-components android-livedata






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Jun 8 '17 at 6:39









CodeCameoCodeCameo

1,45021322




1,45021322








  • 1





    But why you want to use sections.getValue(), while livedata are used to observe the data. May be when you are checking in next line, data is not set in livedata that's why it gives you null. In short if you don't want to use LiveData then just use it without LiveData.

    – Moinkhan
    Jun 8 '17 at 8:42






  • 2





    I want to use livedata...if sections.getValue() is null I have to call api for data and insert in into the database which will eventually call the onChange() method from where I will get the data. But Because of that null value if and getting data from both database and api.

    – CodeCameo
    Jun 8 '17 at 12:13











  • I'll just add that, it is helpful to know that onChanged is also called the first time the data is initialized/ready, so you don't have to do the initial data retrieval yourself.

    – Karuhanga
    Jul 1 '18 at 2:40











  • Exact same problem here. I too am checking if there is value in database, and if there is not then I have to call APIte get datat which then saves the data in Database. Still no solution for me. Android MVVM sucks !

    – zulkarnain shah
    Jul 26 '18 at 11:00














  • 1





    But why you want to use sections.getValue(), while livedata are used to observe the data. May be when you are checking in next line, data is not set in livedata that's why it gives you null. In short if you don't want to use LiveData then just use it without LiveData.

    – Moinkhan
    Jun 8 '17 at 8:42






  • 2





    I want to use livedata...if sections.getValue() is null I have to call api for data and insert in into the database which will eventually call the onChange() method from where I will get the data. But Because of that null value if and getting data from both database and api.

    – CodeCameo
    Jun 8 '17 at 12:13











  • I'll just add that, it is helpful to know that onChanged is also called the first time the data is initialized/ready, so you don't have to do the initial data retrieval yourself.

    – Karuhanga
    Jul 1 '18 at 2:40











  • Exact same problem here. I too am checking if there is value in database, and if there is not then I have to call APIte get datat which then saves the data in Database. Still no solution for me. Android MVVM sucks !

    – zulkarnain shah
    Jul 26 '18 at 11:00








1




1





But why you want to use sections.getValue(), while livedata are used to observe the data. May be when you are checking in next line, data is not set in livedata that's why it gives you null. In short if you don't want to use LiveData then just use it without LiveData.

– Moinkhan
Jun 8 '17 at 8:42





But why you want to use sections.getValue(), while livedata are used to observe the data. May be when you are checking in next line, data is not set in livedata that's why it gives you null. In short if you don't want to use LiveData then just use it without LiveData.

– Moinkhan
Jun 8 '17 at 8:42




2




2





I want to use livedata...if sections.getValue() is null I have to call api for data and insert in into the database which will eventually call the onChange() method from where I will get the data. But Because of that null value if and getting data from both database and api.

– CodeCameo
Jun 8 '17 at 12:13





I want to use livedata...if sections.getValue() is null I have to call api for data and insert in into the database which will eventually call the onChange() method from where I will get the data. But Because of that null value if and getting data from both database and api.

– CodeCameo
Jun 8 '17 at 12:13













I'll just add that, it is helpful to know that onChanged is also called the first time the data is initialized/ready, so you don't have to do the initial data retrieval yourself.

– Karuhanga
Jul 1 '18 at 2:40





I'll just add that, it is helpful to know that onChanged is also called the first time the data is initialized/ready, so you don't have to do the initial data retrieval yourself.

– Karuhanga
Jul 1 '18 at 2:40













Exact same problem here. I too am checking if there is value in database, and if there is not then I have to call APIte get datat which then saves the data in Database. Still no solution for me. Android MVVM sucks !

– zulkarnain shah
Jul 26 '18 at 11:00





Exact same problem here. I too am checking if there is value in database, and if there is not then I have to call APIte get datat which then saves the data in Database. Still no solution for me. Android MVVM sucks !

– zulkarnain shah
Jul 26 '18 at 11:00












5 Answers
5






active

oldest

votes


















14














I solve this problem through this approach



    private MediatorLiveData<List<Section>> mSectionLive = new MediatorLiveData<>();
.
.
.

@Override
public LiveData<List<Section>> getAllSections() {
final LiveData<List<Section>> sections = mDb.sectionDAO().getAllSections();

mSectionLive.addSource(sections, new Observer<List<Section>>() {
@Override
public void onChanged(@Nullable List<Section> sectionList) {
if(sectionList == null || sectionList.isEmpty()) {
// Fetch data from API
}else{
mSectionLive.removeSource(sections);
mSectionLive.setValue(sectionList);
}
}
});
return mSectionLive;
}





share|improve this answer
























  • Can you help me? I'm facing the same problem, where should I put this code?

    – Douglas Fornaro
    Sep 21 '17 at 2:24











  • You can find it here... github.com/codecameo/Shobdho

    – CodeCameo
    Sep 22 '17 at 10:02











  • Just in case anyone is facing the same issue, the solution lies on the MediatorLiveData which is a sub-class that can observe on other LiveData.

    – Rodrigo Queiroz
    Nov 15 '17 at 12:46






  • 3





    From what I can tell, the MediatorData is completely unnecessary. you can add an Observer directly to the original LiveData with sections.observer().

    – Code-Apprentice
    Jul 29 '18 at 18:39



















9















On the next line I am checking sections.getValue() which is always giving me null although I have data in the DataBase and later I am getting the value in the onChanged() method.




This is a normal behavior, because queries that return LiveData, are working asynchronous. The value is null that moment.



So calling this method



LiveData<List<Section>> getAllSections();


you will get the result later here



sections.observe(this, new Observer<List<Section>>() {
@Override
public void onChanged(@Nullable List<Section> sections){

}
});


from documentation:




Room does not allow accessing the database on the main thread unless you called allowMainThreadQueries() on the builder because it might potentially lock the UI for a long periods of time. Asynchronous queries (queries that return LiveData or RxJava Flowable) are exempt from this rule since they asynchronously run the query on a background thread when needed.







share|improve this answer

































    2















    if sections.getValue() is null I have to call api for data and insert
    in into the database




    You can handle this at onChange method:



    sections.observe(this, new Observer<List<Section>>() {
    @Override
    public void onChanged(@Nullable List<Section> sections){
    if(sections == null || sections.size() == 0) {
    // No data in your database, call your api for data
    } else {
    // One or more items retrieved, no need to call your api for data.
    }
    }
    });


    But you should better put this Database/Table initialization logic to a repository class. Check out Google's sample. See DatabaseCreator class.






    share|improve this answer


























    • I have already seen that example and the problem with this is, every time the application is launched createDb(Context context) is getting called though it has data cause initially isDatabaseCreated() will always return false.

      – CodeCameo
      Jun 10 '17 at 6:08



















    2














    I resolved the similar issue as follows



    Inside your ViewModel class



    private LiveData<List<Section>> mSections;

    @Override
    public LiveData<List<Section>> getAllSections() {

    if (mSections == null) {
    mSections = mDb.sectionDAO().getAllSections();
    }

    return mSections;
    }


    This is all required. Never change the LiveData's instance.






    share|improve this answer































      1














      LiveData is an asynchronous query, you get the LiveData object but it might contain no data. You could use an extra method to wait for the data to be filled then extract the data.



      public static <T> T getValue(LiveData<T> liveData) throws InterruptedException {
      final Object objects = new Object[1];
      final CountDownLatch latch = new CountDownLatch(1);

      Observer observer = new Observer() {
      @Override
      public void onChanged(@Nullable Object o) {
      objects[0] = o;
      latch.countDown();
      liveData.removeObserver(this);
      }
      };
      liveData.observeForever(observer);
      latch.await(2, TimeUnit.SECONDS);
      return (T) objects[0];
      }





      share|improve this answer
























      • could you explain whats happening here exactly? a 2 sec wait?

        – ir2pid
        Jul 13 '18 at 9:38






      • 1





        current thread wait at most 2 seconds until the latch has counted down to zero

        – Yanbin Hu
        Jul 14 '18 at 12:02












      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f44428389%2flivedata-getvalue-returns-null-with-room%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      5 Answers
      5






      active

      oldest

      votes








      5 Answers
      5






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      14














      I solve this problem through this approach



          private MediatorLiveData<List<Section>> mSectionLive = new MediatorLiveData<>();
      .
      .
      .

      @Override
      public LiveData<List<Section>> getAllSections() {
      final LiveData<List<Section>> sections = mDb.sectionDAO().getAllSections();

      mSectionLive.addSource(sections, new Observer<List<Section>>() {
      @Override
      public void onChanged(@Nullable List<Section> sectionList) {
      if(sectionList == null || sectionList.isEmpty()) {
      // Fetch data from API
      }else{
      mSectionLive.removeSource(sections);
      mSectionLive.setValue(sectionList);
      }
      }
      });
      return mSectionLive;
      }





      share|improve this answer
























      • Can you help me? I'm facing the same problem, where should I put this code?

        – Douglas Fornaro
        Sep 21 '17 at 2:24











      • You can find it here... github.com/codecameo/Shobdho

        – CodeCameo
        Sep 22 '17 at 10:02











      • Just in case anyone is facing the same issue, the solution lies on the MediatorLiveData which is a sub-class that can observe on other LiveData.

        – Rodrigo Queiroz
        Nov 15 '17 at 12:46






      • 3





        From what I can tell, the MediatorData is completely unnecessary. you can add an Observer directly to the original LiveData with sections.observer().

        – Code-Apprentice
        Jul 29 '18 at 18:39
















      14














      I solve this problem through this approach



          private MediatorLiveData<List<Section>> mSectionLive = new MediatorLiveData<>();
      .
      .
      .

      @Override
      public LiveData<List<Section>> getAllSections() {
      final LiveData<List<Section>> sections = mDb.sectionDAO().getAllSections();

      mSectionLive.addSource(sections, new Observer<List<Section>>() {
      @Override
      public void onChanged(@Nullable List<Section> sectionList) {
      if(sectionList == null || sectionList.isEmpty()) {
      // Fetch data from API
      }else{
      mSectionLive.removeSource(sections);
      mSectionLive.setValue(sectionList);
      }
      }
      });
      return mSectionLive;
      }





      share|improve this answer
























      • Can you help me? I'm facing the same problem, where should I put this code?

        – Douglas Fornaro
        Sep 21 '17 at 2:24











      • You can find it here... github.com/codecameo/Shobdho

        – CodeCameo
        Sep 22 '17 at 10:02











      • Just in case anyone is facing the same issue, the solution lies on the MediatorLiveData which is a sub-class that can observe on other LiveData.

        – Rodrigo Queiroz
        Nov 15 '17 at 12:46






      • 3





        From what I can tell, the MediatorData is completely unnecessary. you can add an Observer directly to the original LiveData with sections.observer().

        – Code-Apprentice
        Jul 29 '18 at 18:39














      14












      14








      14







      I solve this problem through this approach



          private MediatorLiveData<List<Section>> mSectionLive = new MediatorLiveData<>();
      .
      .
      .

      @Override
      public LiveData<List<Section>> getAllSections() {
      final LiveData<List<Section>> sections = mDb.sectionDAO().getAllSections();

      mSectionLive.addSource(sections, new Observer<List<Section>>() {
      @Override
      public void onChanged(@Nullable List<Section> sectionList) {
      if(sectionList == null || sectionList.isEmpty()) {
      // Fetch data from API
      }else{
      mSectionLive.removeSource(sections);
      mSectionLive.setValue(sectionList);
      }
      }
      });
      return mSectionLive;
      }





      share|improve this answer













      I solve this problem through this approach



          private MediatorLiveData<List<Section>> mSectionLive = new MediatorLiveData<>();
      .
      .
      .

      @Override
      public LiveData<List<Section>> getAllSections() {
      final LiveData<List<Section>> sections = mDb.sectionDAO().getAllSections();

      mSectionLive.addSource(sections, new Observer<List<Section>>() {
      @Override
      public void onChanged(@Nullable List<Section> sectionList) {
      if(sectionList == null || sectionList.isEmpty()) {
      // Fetch data from API
      }else{
      mSectionLive.removeSource(sections);
      mSectionLive.setValue(sectionList);
      }
      }
      });
      return mSectionLive;
      }






      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Jun 10 '17 at 8:49









      CodeCameoCodeCameo

      1,45021322




      1,45021322













      • Can you help me? I'm facing the same problem, where should I put this code?

        – Douglas Fornaro
        Sep 21 '17 at 2:24











      • You can find it here... github.com/codecameo/Shobdho

        – CodeCameo
        Sep 22 '17 at 10:02











      • Just in case anyone is facing the same issue, the solution lies on the MediatorLiveData which is a sub-class that can observe on other LiveData.

        – Rodrigo Queiroz
        Nov 15 '17 at 12:46






      • 3





        From what I can tell, the MediatorData is completely unnecessary. you can add an Observer directly to the original LiveData with sections.observer().

        – Code-Apprentice
        Jul 29 '18 at 18:39



















      • Can you help me? I'm facing the same problem, where should I put this code?

        – Douglas Fornaro
        Sep 21 '17 at 2:24











      • You can find it here... github.com/codecameo/Shobdho

        – CodeCameo
        Sep 22 '17 at 10:02











      • Just in case anyone is facing the same issue, the solution lies on the MediatorLiveData which is a sub-class that can observe on other LiveData.

        – Rodrigo Queiroz
        Nov 15 '17 at 12:46






      • 3





        From what I can tell, the MediatorData is completely unnecessary. you can add an Observer directly to the original LiveData with sections.observer().

        – Code-Apprentice
        Jul 29 '18 at 18:39

















      Can you help me? I'm facing the same problem, where should I put this code?

      – Douglas Fornaro
      Sep 21 '17 at 2:24





      Can you help me? I'm facing the same problem, where should I put this code?

      – Douglas Fornaro
      Sep 21 '17 at 2:24













      You can find it here... github.com/codecameo/Shobdho

      – CodeCameo
      Sep 22 '17 at 10:02





      You can find it here... github.com/codecameo/Shobdho

      – CodeCameo
      Sep 22 '17 at 10:02













      Just in case anyone is facing the same issue, the solution lies on the MediatorLiveData which is a sub-class that can observe on other LiveData.

      – Rodrigo Queiroz
      Nov 15 '17 at 12:46





      Just in case anyone is facing the same issue, the solution lies on the MediatorLiveData which is a sub-class that can observe on other LiveData.

      – Rodrigo Queiroz
      Nov 15 '17 at 12:46




      3




      3





      From what I can tell, the MediatorData is completely unnecessary. you can add an Observer directly to the original LiveData with sections.observer().

      – Code-Apprentice
      Jul 29 '18 at 18:39





      From what I can tell, the MediatorData is completely unnecessary. you can add an Observer directly to the original LiveData with sections.observer().

      – Code-Apprentice
      Jul 29 '18 at 18:39













      9















      On the next line I am checking sections.getValue() which is always giving me null although I have data in the DataBase and later I am getting the value in the onChanged() method.




      This is a normal behavior, because queries that return LiveData, are working asynchronous. The value is null that moment.



      So calling this method



      LiveData<List<Section>> getAllSections();


      you will get the result later here



      sections.observe(this, new Observer<List<Section>>() {
      @Override
      public void onChanged(@Nullable List<Section> sections){

      }
      });


      from documentation:




      Room does not allow accessing the database on the main thread unless you called allowMainThreadQueries() on the builder because it might potentially lock the UI for a long periods of time. Asynchronous queries (queries that return LiveData or RxJava Flowable) are exempt from this rule since they asynchronously run the query on a background thread when needed.







      share|improve this answer






























        9















        On the next line I am checking sections.getValue() which is always giving me null although I have data in the DataBase and later I am getting the value in the onChanged() method.




        This is a normal behavior, because queries that return LiveData, are working asynchronous. The value is null that moment.



        So calling this method



        LiveData<List<Section>> getAllSections();


        you will get the result later here



        sections.observe(this, new Observer<List<Section>>() {
        @Override
        public void onChanged(@Nullable List<Section> sections){

        }
        });


        from documentation:




        Room does not allow accessing the database on the main thread unless you called allowMainThreadQueries() on the builder because it might potentially lock the UI for a long periods of time. Asynchronous queries (queries that return LiveData or RxJava Flowable) are exempt from this rule since they asynchronously run the query on a background thread when needed.







        share|improve this answer




























          9












          9








          9








          On the next line I am checking sections.getValue() which is always giving me null although I have data in the DataBase and later I am getting the value in the onChanged() method.




          This is a normal behavior, because queries that return LiveData, are working asynchronous. The value is null that moment.



          So calling this method



          LiveData<List<Section>> getAllSections();


          you will get the result later here



          sections.observe(this, new Observer<List<Section>>() {
          @Override
          public void onChanged(@Nullable List<Section> sections){

          }
          });


          from documentation:




          Room does not allow accessing the database on the main thread unless you called allowMainThreadQueries() on the builder because it might potentially lock the UI for a long periods of time. Asynchronous queries (queries that return LiveData or RxJava Flowable) are exempt from this rule since they asynchronously run the query on a background thread when needed.







          share|improve this answer
















          On the next line I am checking sections.getValue() which is always giving me null although I have data in the DataBase and later I am getting the value in the onChanged() method.




          This is a normal behavior, because queries that return LiveData, are working asynchronous. The value is null that moment.



          So calling this method



          LiveData<List<Section>> getAllSections();


          you will get the result later here



          sections.observe(this, new Observer<List<Section>>() {
          @Override
          public void onChanged(@Nullable List<Section> sections){

          }
          });


          from documentation:




          Room does not allow accessing the database on the main thread unless you called allowMainThreadQueries() on the builder because it might potentially lock the UI for a long periods of time. Asynchronous queries (queries that return LiveData or RxJava Flowable) are exempt from this rule since they asynchronously run the query on a background thread when needed.








          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Jan 3 at 18:17

























          answered Oct 31 '17 at 11:18









          snersesyansnersesyan

          570516




          570516























              2















              if sections.getValue() is null I have to call api for data and insert
              in into the database




              You can handle this at onChange method:



              sections.observe(this, new Observer<List<Section>>() {
              @Override
              public void onChanged(@Nullable List<Section> sections){
              if(sections == null || sections.size() == 0) {
              // No data in your database, call your api for data
              } else {
              // One or more items retrieved, no need to call your api for data.
              }
              }
              });


              But you should better put this Database/Table initialization logic to a repository class. Check out Google's sample. See DatabaseCreator class.






              share|improve this answer


























              • I have already seen that example and the problem with this is, every time the application is launched createDb(Context context) is getting called though it has data cause initially isDatabaseCreated() will always return false.

                – CodeCameo
                Jun 10 '17 at 6:08
















              2















              if sections.getValue() is null I have to call api for data and insert
              in into the database




              You can handle this at onChange method:



              sections.observe(this, new Observer<List<Section>>() {
              @Override
              public void onChanged(@Nullable List<Section> sections){
              if(sections == null || sections.size() == 0) {
              // No data in your database, call your api for data
              } else {
              // One or more items retrieved, no need to call your api for data.
              }
              }
              });


              But you should better put this Database/Table initialization logic to a repository class. Check out Google's sample. See DatabaseCreator class.






              share|improve this answer


























              • I have already seen that example and the problem with this is, every time the application is launched createDb(Context context) is getting called though it has data cause initially isDatabaseCreated() will always return false.

                – CodeCameo
                Jun 10 '17 at 6:08














              2












              2








              2








              if sections.getValue() is null I have to call api for data and insert
              in into the database




              You can handle this at onChange method:



              sections.observe(this, new Observer<List<Section>>() {
              @Override
              public void onChanged(@Nullable List<Section> sections){
              if(sections == null || sections.size() == 0) {
              // No data in your database, call your api for data
              } else {
              // One or more items retrieved, no need to call your api for data.
              }
              }
              });


              But you should better put this Database/Table initialization logic to a repository class. Check out Google's sample. See DatabaseCreator class.






              share|improve this answer
















              if sections.getValue() is null I have to call api for data and insert
              in into the database




              You can handle this at onChange method:



              sections.observe(this, new Observer<List<Section>>() {
              @Override
              public void onChanged(@Nullable List<Section> sections){
              if(sections == null || sections.size() == 0) {
              // No data in your database, call your api for data
              } else {
              // One or more items retrieved, no need to call your api for data.
              }
              }
              });


              But you should better put this Database/Table initialization logic to a repository class. Check out Google's sample. See DatabaseCreator class.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Jun 9 '17 at 13:34

























              answered Jun 9 '17 at 13:27









              DevrimDevrim

              12.2k34666




              12.2k34666













              • I have already seen that example and the problem with this is, every time the application is launched createDb(Context context) is getting called though it has data cause initially isDatabaseCreated() will always return false.

                – CodeCameo
                Jun 10 '17 at 6:08



















              • I have already seen that example and the problem with this is, every time the application is launched createDb(Context context) is getting called though it has data cause initially isDatabaseCreated() will always return false.

                – CodeCameo
                Jun 10 '17 at 6:08

















              I have already seen that example and the problem with this is, every time the application is launched createDb(Context context) is getting called though it has data cause initially isDatabaseCreated() will always return false.

              – CodeCameo
              Jun 10 '17 at 6:08





              I have already seen that example and the problem with this is, every time the application is launched createDb(Context context) is getting called though it has data cause initially isDatabaseCreated() will always return false.

              – CodeCameo
              Jun 10 '17 at 6:08











              2














              I resolved the similar issue as follows



              Inside your ViewModel class



              private LiveData<List<Section>> mSections;

              @Override
              public LiveData<List<Section>> getAllSections() {

              if (mSections == null) {
              mSections = mDb.sectionDAO().getAllSections();
              }

              return mSections;
              }


              This is all required. Never change the LiveData's instance.






              share|improve this answer




























                2














                I resolved the similar issue as follows



                Inside your ViewModel class



                private LiveData<List<Section>> mSections;

                @Override
                public LiveData<List<Section>> getAllSections() {

                if (mSections == null) {
                mSections = mDb.sectionDAO().getAllSections();
                }

                return mSections;
                }


                This is all required. Never change the LiveData's instance.






                share|improve this answer


























                  2












                  2








                  2







                  I resolved the similar issue as follows



                  Inside your ViewModel class



                  private LiveData<List<Section>> mSections;

                  @Override
                  public LiveData<List<Section>> getAllSections() {

                  if (mSections == null) {
                  mSections = mDb.sectionDAO().getAllSections();
                  }

                  return mSections;
                  }


                  This is all required. Never change the LiveData's instance.






                  share|improve this answer













                  I resolved the similar issue as follows



                  Inside your ViewModel class



                  private LiveData<List<Section>> mSections;

                  @Override
                  public LiveData<List<Section>> getAllSections() {

                  if (mSections == null) {
                  mSections = mDb.sectionDAO().getAllSections();
                  }

                  return mSections;
                  }


                  This is all required. Never change the LiveData's instance.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Oct 13 '17 at 13:07









                  NapoleanNapolean

                  1,8431729




                  1,8431729























                      1














                      LiveData is an asynchronous query, you get the LiveData object but it might contain no data. You could use an extra method to wait for the data to be filled then extract the data.



                      public static <T> T getValue(LiveData<T> liveData) throws InterruptedException {
                      final Object objects = new Object[1];
                      final CountDownLatch latch = new CountDownLatch(1);

                      Observer observer = new Observer() {
                      @Override
                      public void onChanged(@Nullable Object o) {
                      objects[0] = o;
                      latch.countDown();
                      liveData.removeObserver(this);
                      }
                      };
                      liveData.observeForever(observer);
                      latch.await(2, TimeUnit.SECONDS);
                      return (T) objects[0];
                      }





                      share|improve this answer
























                      • could you explain whats happening here exactly? a 2 sec wait?

                        – ir2pid
                        Jul 13 '18 at 9:38






                      • 1





                        current thread wait at most 2 seconds until the latch has counted down to zero

                        – Yanbin Hu
                        Jul 14 '18 at 12:02
















                      1














                      LiveData is an asynchronous query, you get the LiveData object but it might contain no data. You could use an extra method to wait for the data to be filled then extract the data.



                      public static <T> T getValue(LiveData<T> liveData) throws InterruptedException {
                      final Object objects = new Object[1];
                      final CountDownLatch latch = new CountDownLatch(1);

                      Observer observer = new Observer() {
                      @Override
                      public void onChanged(@Nullable Object o) {
                      objects[0] = o;
                      latch.countDown();
                      liveData.removeObserver(this);
                      }
                      };
                      liveData.observeForever(observer);
                      latch.await(2, TimeUnit.SECONDS);
                      return (T) objects[0];
                      }





                      share|improve this answer
























                      • could you explain whats happening here exactly? a 2 sec wait?

                        – ir2pid
                        Jul 13 '18 at 9:38






                      • 1





                        current thread wait at most 2 seconds until the latch has counted down to zero

                        – Yanbin Hu
                        Jul 14 '18 at 12:02














                      1












                      1








                      1







                      LiveData is an asynchronous query, you get the LiveData object but it might contain no data. You could use an extra method to wait for the data to be filled then extract the data.



                      public static <T> T getValue(LiveData<T> liveData) throws InterruptedException {
                      final Object objects = new Object[1];
                      final CountDownLatch latch = new CountDownLatch(1);

                      Observer observer = new Observer() {
                      @Override
                      public void onChanged(@Nullable Object o) {
                      objects[0] = o;
                      latch.countDown();
                      liveData.removeObserver(this);
                      }
                      };
                      liveData.observeForever(observer);
                      latch.await(2, TimeUnit.SECONDS);
                      return (T) objects[0];
                      }





                      share|improve this answer













                      LiveData is an asynchronous query, you get the LiveData object but it might contain no data. You could use an extra method to wait for the data to be filled then extract the data.



                      public static <T> T getValue(LiveData<T> liveData) throws InterruptedException {
                      final Object objects = new Object[1];
                      final CountDownLatch latch = new CountDownLatch(1);

                      Observer observer = new Observer() {
                      @Override
                      public void onChanged(@Nullable Object o) {
                      objects[0] = o;
                      latch.countDown();
                      liveData.removeObserver(this);
                      }
                      };
                      liveData.observeForever(observer);
                      latch.await(2, TimeUnit.SECONDS);
                      return (T) objects[0];
                      }






                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Apr 6 '18 at 13:17









                      Yanbin HuYanbin Hu

                      426414




                      426414













                      • could you explain whats happening here exactly? a 2 sec wait?

                        – ir2pid
                        Jul 13 '18 at 9:38






                      • 1





                        current thread wait at most 2 seconds until the latch has counted down to zero

                        – Yanbin Hu
                        Jul 14 '18 at 12:02



















                      • could you explain whats happening here exactly? a 2 sec wait?

                        – ir2pid
                        Jul 13 '18 at 9:38






                      • 1





                        current thread wait at most 2 seconds until the latch has counted down to zero

                        – Yanbin Hu
                        Jul 14 '18 at 12:02

















                      could you explain whats happening here exactly? a 2 sec wait?

                      – ir2pid
                      Jul 13 '18 at 9:38





                      could you explain whats happening here exactly? a 2 sec wait?

                      – ir2pid
                      Jul 13 '18 at 9:38




                      1




                      1





                      current thread wait at most 2 seconds until the latch has counted down to zero

                      – Yanbin Hu
                      Jul 14 '18 at 12:02





                      current thread wait at most 2 seconds until the latch has counted down to zero

                      – Yanbin Hu
                      Jul 14 '18 at 12:02


















                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f44428389%2flivedata-getvalue-returns-null-with-room%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Monofisismo

                      Angular Downloading a file using contenturl with Basic Authentication

                      Olmecas