# Migrate to stable structures and use how to store vectors in ic stable structures

**URL:** <https://forum.dfinity.org/t/migrate-to-stable-structures-and-use-how-to-store-vectors-in-ic-stable-structures/36599>\
**Category:** Developers\
**Tags:** Discussing\
**Created:** [October 27, 2024, 5:44am UTC](https://forum.dfinity.org/t/migrate-to-stable-structures-and-use-how-to-store-vectors-in-ic-stable-structures/36599 "2024-10-27T05:44:45Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![AliSci](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/alisci/32/33799_2.png) [@AliSci](https://forum.dfinity.org/u/AliSci)\
**Post date:** [October 27, 2024, 5:44am UTC](https://forum.dfinity.org/t/migrate-to-stable-structures-and-use-how-to-store-vectors-in-ic-stable-structures/36599/1 "2024-10-27T05:44:45Z")

</div>

i had somthing like

```rs
static USER_FILES: RefCell<Vec<FilesStore>> = RefCell::default();

```

now I convert it to

```auto

#[derive(Clone, Debug, Deserialize, CandidType)]
pub struct FileNodeVector {
    pub files: Vec<FileNode>,
}

impl Storable for FileNodeVector {
    fn to_bytes(&self) -> Cow<[u8]> {
        Cow::Owned(Encode!(self).unwrap())
    }

    fn from_bytes(bytes: Cow<[u8]>) -> Self {
        Decode!(bytes.as_ref(), Self).unwrap()
    }

    const BOUND: Bound = Bound::Unbounded;
}

static USER_FILES: RefCell<StableBTreeMap<String, FileNodeVector, Memory>> = RefCell::new(
        StableBTreeMap::init(
            MEMORY_MANAGER.with(|m| m.borrow().get(MemoryId::new(3))),
        )
    );

```

No the problem is I have to adjust all of my functions that uses `SHARED_USER_FILES.with(|files_share_store| {` which is a long painful process any alternatives ways to migrate?

---

<div class="post-metadata">

**Author:** ![dsarlis](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/dsarlis/32/689_2.png) [@dsarlis](https://forum.dfinity.org/u/dsarlis)\
**Post date:** [October 29, 2024, 10:07am UTC](https://forum.dfinity.org/t/migrate-to-stable-structures-and-use-how-to-store-vectors-in-ic-stable-structures/36599/2 "2024-10-29T10:07:55Z")

</div>

Using the `with` syntax comes usually from using a `thread_local` which is irrespective of whether you use stable structures or not (it’s a Rust thing). Maybe you were using a simple `static` variable before (seems likely given the code snippet you shared) and now that you switch to stable structures you also introduced a `thread_local` (as we have in examples using stable structures)? In fact, we do recommend using a `thread_local` instead of a plain static variable.

---

<div class="post-metadata">

**Author:** ![AliSci](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/alisci/32/33799_2.png) [@AliSci](https://forum.dfinity.org/u/AliSci)\
**Post date:** [November 1, 2024, 5:34am UTC](https://forum.dfinity.org/t/migrate-to-stable-structures-and-use-how-to-store-vectors-in-ic-stable-structures/36599/3 "2024-11-01T05:34:43Z")

</div>

> [@dsarlis](#):
>
> thread\_local

in fact we are already using thread local.

 ![Screenshot 2024-11-01 at 1.33.49 PM](https://us1.discourse-cdn.com/flex023/uploads/dfn/original/3X/7/d/7d8618ef060fedd6b8745bb5170cc0e584cc213a.png)

# can I also do it like ?

```rs
use ic_stable_structures::{
    storable::Bound, DefaultMemoryImpl, StableBTreeMap, Storable, StableVec,
};

thread_local! {
static MEMORY_MANAGER: RefCell<MemoryManager<DefaultMemoryImpl>> =
        RefCell::new(MemoryManager::init(DefaultMemoryImpl::default()));

static NOTIFICATIONS: RefCell<StableBTreeMap<String, StableVec<Notification,Memory>, Memory>> = RefCell::new(
        StableBTreeMap::init(
            MEMORY_MANAGER.with(|m| m.borrow().get(MemoryId::new(9))),
        )
    );
|

```

---

<div class="post-metadata">

**Author:** ![dsarlis](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/dsarlis/32/689_2.png) [@dsarlis](https://forum.dfinity.org/u/dsarlis)\
**Post date:** [November 1, 2024, 8:58am UTC](https://forum.dfinity.org/t/migrate-to-stable-structures-and-use-how-to-store-vectors-in-ic-stable-structures/36599/4 "2024-11-01T08:58:55Z")

</div>

Perhaps I misunderstood the original message then. Can you show an example of what kind of change you had to do in your functions?

---

<div class="post-metadata">

**Author:** ![AliSci](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/alisci/32/33799_2.png) [@AliSci](https://forum.dfinity.org/u/AliSci)\
**Post date:** [November 2, 2024, 6:29am UTC](https://forum.dfinity.org/t/migrate-to-stable-structures-and-use-how-to-store-vectors-in-ic-stable-structures/36599/5 "2024-11-02T06:29:20Z")

</div>

```rs
POSTS.with(|posts| {
            posts.borrow_mut().insert(id.clone(), self.clone());
        });

```

I don’t know which function u ment? but I don’t think it mattes here  
what matter how to make the static that store vectors, I wish u can help me with a google meet call.

# Goal

Store data like this `<UserIdString, Vec<StructContractWhatever>>`

 ![Screenshot 2024-11-02 at 2.37.39 PM](https://us1.discourse-cdn.com/flex023/uploads/dfn/original/3X/9/7/975ef516f09aafa55751f63caeb03f55d3eb91e7.png)

---

<div class="post-metadata">

**Author:** ![dsarlis](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/dsarlis/32/689_2.png) [@dsarlis](https://forum.dfinity.org/u/dsarlis)\
**Post date:** [November 4, 2024, 8:50am UTC](https://forum.dfinity.org/t/migrate-to-stable-structures-and-use-how-to-store-vectors-in-ic-stable-structures/36599/6 "2024-11-04T08:50:29Z")

</div>

I think I now got it looking at your previous comment as well.

Stable structures cannot be nested at the moment. So

```auto
static NOTIFICATIONS: RefCell<StableBTreeMap<String, StableVec<Notification,Memory>, Memory>> = RefCell::new(
        StableBTreeMap::init(
            MEMORY_MANAGER.with(|m| m.borrow().get(MemoryId::new(9))),
        )
    );

```

would not work as you try to store a `StableVec` inside a `StableBTreeMap. Either you'd need to use a normal `Vec` but of course it wouldn’t be as efficient (you’d need to rewrite the whole vector every time) or you’d need to design your StableBTreeMap with a composite key so that you can store multiple entries that share some part of the key (and another could be different).

You can read about using composite keys in [this useful blog](https://mmapped.blog/posts/14-stable-structures#data-structures) from Roman.

---

<div class="post-metadata">

**Author:** ![AliSci](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/alisci/32/33799_2.png) [@AliSci](https://forum.dfinity.org/u/AliSci)\
**Post date:** [November 5, 2024, 8:03am UTC](https://forum.dfinity.org/t/migrate-to-stable-structures-and-use-how-to-store-vectors-in-ic-stable-structures/36599/7 "2024-11-05T08:03:24Z")

</div>

I ried use normal Vec but it shows srotable not implement for vec

---

<div class="post-metadata">

**Author:** ![dsarlis](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/dsarlis/32/689_2.png) [@dsarlis](https://forum.dfinity.org/u/dsarlis)\
**Post date:** [November 5, 2024, 8:44am UTC](https://forum.dfinity.org/t/migrate-to-stable-structures-and-use-how-to-store-vectors-in-ic-stable-structures/36599/8 "2024-11-05T08:44:06Z")

</div>

Sure, but that’s not a hard error though. You need to implement `Storable` yourself (as you have to for any custom type you want to store in the StableBTreeMap).

---

<div class="post-metadata">

**Author:** ![AliSci](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/alisci/32/33799_2.png) [@AliSci](https://forum.dfinity.org/u/AliSci)\
**Post date:** [November 5, 2024, 9:02am UTC](https://forum.dfinity.org/t/migrate-to-stable-structures-and-use-how-to-store-vectors-in-ic-stable-structures/36599/9 "2024-11-05T09:02:50Z")

</div>

do u mean `impl storable for Vec`

---

<div class="post-metadata">

**Author:** ![dsarlis](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/dsarlis/32/689_2.png) [@dsarlis](https://forum.dfinity.org/u/dsarlis)\
**Post date:** [November 5, 2024, 9:12am UTC](https://forum.dfinity.org/t/migrate-to-stable-structures-and-use-how-to-store-vectors-in-ic-stable-structures/36599/10 "2024-11-05T09:12:25Z")

</div>

Yeah or you define your own type that wraps `Vec<Data>` and implement it for that. Whatever works best for you.

---

<div class="post-metadata">

**Author:** ![AliSci](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/alisci/32/33799_2.png) [@AliSci](https://forum.dfinity.org/u/AliSci)\
**Post date:** [November 6, 2024, 3:54am UTC](https://forum.dfinity.org/t/migrate-to-stable-structures-and-use-how-to-store-vectors-in-ic-stable-structures/36599/11 "2024-11-06T03:54:43Z")

</div>

# Failed to decode StoredContractVec

This error seams to be genrtaed from StoredContractVec but it actlyally happedn after calling `FRIENDS_STORE.with(|friends_store| {...`  
Now, I just follow all ur steps but I am getting this error

````rs
{
  "Message": "IC0503: Error from Canister bkyz2-fmaaa-aaaaa-qaaaq-cai: Canister called `ic0.trap` with message: Failed to decode StoredContractVec: Custom(Fail to decode argument 0 from table0 to record {
    friends : vec record {
      sender : record {
        id : text;
        name : text;
        description : text;
        photo : blob;
      };
      confirmed : bool;
      receiver : record {
        id : text;
        name : text;
        description : text;
        photo : blob;
      };
    };
  }

  Caused by:
    Subtyping error: Type mismatch at /Users/ahmed/.cargo/registry/src/index.crates.io-6f17d22bba15001f/candid-0.10.10/src/de.rs:882).
Consider gracefully handling failures from this canister or altering the canister to handle exceptions. See documentation: http://internetcomputer.org/docs/current/references/execution-errors#trapped-explicitly"
}
``
my code
```lib.rs
thread_local! {
static FRIENDS_STORE: RefCell<StableBTreeMap<String, FriendVec, Memory>> = RefCell::new(
        StableBTreeMap::init(
            MEMORY_MANAGER.with(|m| m.borrow().get(MemoryId::new(6))),
        )
    );
static CONTRACTS_STORE: RefCell<StableBTreeMap<String, StoredContractVec, Memory>> = RefCell::new(
        StableBTreeMap::init(
            MEMORY_MANAGER.with(|m| m.borrow().get(MemoryId::new(6))),
        )
    );

}

````

```rs
pub fn get_list(user: Principal) -> Vec<Friend> {
        let mut list = vec![];
        FRIENDS_STORE.with(|friends_store| {
            let store = friends_store.borrow();
            if let Some(friends) = store.get(&user.to_string()) {
                list = friends.friends.clone();
            }
        });
        return list;
    }

```

```rs
impl Contract {
    pub fn get_all_contracts() -> Option<HashMap<ContractId, StoredContract>> {
        let mut contract_map = HashMap::new();

        CONTRACTS_STORE.with(|contracts_store| {
            let caller_contracts = contracts_store.borrow();
            if let Some(contracts) = caller_contracts.get(&caller().to_string()) {
                for contract in contracts.stored_contracts.iter() {
                    if let StoredContract::CustomContract(custom_contract) = contract {
                        contract_map.insert(custom_contract.id.clone(), StoredContract::CustomContract(custom_contract.check_view_permission()));
                    }
                }
            }

        });
        Some(contract_map)
    }....

```

---

<div class="post-metadata">

**Author:** ![dsarlis](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/dsarlis/32/689_2.png) [@dsarlis](https://forum.dfinity.org/u/dsarlis)\
**Post date:** [November 7, 2024, 8:39am UTC](https://forum.dfinity.org/t/migrate-to-stable-structures-and-use-how-to-store-vectors-in-ic-stable-structures/36599/12 "2024-11-07T08:39:30Z")

</div>

This now is a candid decoding error. You need to double check whether you’ve correctly implemented the conversion from your Rust type to Candid and back. The error is likely coming from when you try to read the data from stable memory while you’re handling the request to sent to the canister.
