0

I was building my Widgets from a list that was predefined in a file of MyClass I created. This worked but I wanted to be able to store persisted data for adding a Boolean favorite field.

I created the Hive Types/Fields for my class, generated the type adapters, and successfully loaded the Hive box on first run of the app, and I can print values to the console, so I know the data is all there and correct.

In the class I have, name, image url path to asset image and a favorite field.

Before when I was using the list to get my data I was able to get the image URL like this:

Expanded(child: Image.asset(widget.MyClass.imageURL)),

Now I want to get this from the Hive box

Box<MyClass> box = Hive.box<MyClass>('myClassBox');
//This is where I am stuck
Expanded(child: Image.asset(box.???)),

I tried box.values.where and box.get() to then get to imageURL field. But get requires a key, which I don't have to pass it from

Widget build(BuildContext context)

And I then have the same issue when trying to access the favorite field, which I am using the Favorite Button package (favorite_button 0.0.4). And I will then update the true/false value based on the button being tapped.

If someone can point me in the right direction that would be great.

Thanks.

Edit:

Here is the Widget:

Widget build(BuildContext context) => GestureDetector(

    onTap: () => Navigator.of(context).push(MaterialPageRoute(
      builder: (context) => TaskPage(job: widget.job), //Need to get data from Hive now
    )),
    child: Container(
      padding: const EdgeInsets.all(16),
      height: 100,
      decoration: BoxDecoration(
         borderRadius: BorderRadius.circular(16),
      ),
      child: Row(
        children: [
          Expanded(flex: 3, child: buildText()),
          Expanded(child: Image.asset(widget.job.imageUrl)),//Need to get data from Hive now
          GestureDetector(
              child: Icon(
                widget.job.fav ? Icons.favorite : Icons.favorite_border, //Need to get data from Hive now
                
              ),
              onTap: ()  {
                // add/remove from favorites list

              }
          ),

          ],
      ),
    ),
  );

Second Edit: Here is the same code after implementing the suggestion given

Widget build(BuildContext context) => GestureDetector(
    onTap: () => Navigator.of(context).push(MaterialPageRoute(
      builder: (context) => TaskPage(job: Hive.box<Job>('jobBox').get(context)), //This bit is still broken so I need to look at this
    )),

    child: Column(
        children:
        Hive.box<Job>('jobBox').values.toList().map(
                (elementList) => Container(
                padding: const EdgeInsets.all(16),
                height: 100,
                decoration: BoxDecoration(
                  color: white,
                  borderRadius: BorderRadius.circular(16),
                ),
                child: Row(

                    children: [
                    Expanded(flex: 3, child:  Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Text(
                      elementList.name,
                      style: TextStyle(fontWeight: FontWeight.w500, fontSize: 20),
                    ),
                    SizedBox(height: 10),

                    //Text('Num tasks in job'),
                  ],
                )),
                Expanded(child: Image.asset(elementList.imageURL)),
                GestureDetector(
                    child: Icon(
                      elementList.fav
                          ? Icons.favorite
                          : Icons.favorite_border,
                      color: elementList.fav ? Colors.red.shade200 : Colors.grey,
                    ),
                    onTap: () {
                        //To do
                    }
                  // )
                ),
        ],
      ),
    ),
  )
      .toList(),
),
);
rjh500
  • 45
  • 9

1 Answers1

0

Assuming that you have only 1 data in the box, you can access that stored data like this.

Box<MyClass> box = Hive.box<MyClass>('myClassBox');
if(box.isNotEmpty) {
  final data = box.values.first;
  // use data
} else {
  // empty state
}

Hive values could have keys, depending on how you use it. If you used box.put(key, value), you can use box.get(key) to work with keys and values.

If you used box.add(value), it stores the data with auto assigned indexes starting from 0. So you can usebox.getAt(index) to get a data with index.

Pionix
  • 413
  • 2
  • 8
  • Hi, thanks for the answer. I have 20+ bits of data in the box, each with it's own image URL. So I want to loop through and get them all as I did when I crated the widget from a list. – rjh500 May 10 '21 at 15:11
  • You can use `box.values.map((value) => MyWidget()).toList()` to map the box content as a widget list. Or you can just iterate over every data of the `box.values` with a simple loop. But I am not sure if this is what you are asking or not. – Pionix May 11 '21 at 12:40
  • Before I tried to use Hive, this is what I had for my widget see edit in original post. – rjh500 May 11 '21 at 16:07
  • Second edit, I have added my code after your advice. It has almost worked as expected. It seems to loop through and create the widgets more than once, other than that it all looks good. The correct image and Boolean values are all there – rjh500 May 11 '21 at 17:36
  • I don't see any problem with your code in second edit. Maybe there could be duplicate values in your box? To eliminate this possibility, you could try to clear the cache of the application. Or you could clear the box using `box.clear()`. – Pionix May 11 '21 at 20:18
  • I found the error, where I was calling the widget I looped through multiple times by mistake. I forgot to change that code after changing the Widget. Thanks for your help on this! Felt like I was banging my head against a wall – rjh500 May 12 '21 at 14:28