0

I need to add an item in storage but when I build the project, I get this error:

error[E0609]: no field storeId on type &mut std::option::Option<BusinessInfo<T>> --> pallets/bussines/src/lib.rs:171:25 | 171 | ensure!((Some(store.storeId) == Some(store_id)), <Error>::StoreItemNotFound);

I don't know what the problem is.

this is BusinessInfo struct:

#[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)]
#[scale_info(skip_type_params(T))]
#[codec(mel_bound())]
pub struct BusinessInfo<T: Config> {
    logo: Vec<u8>,
    storeId: [u8; 16],
    owner: <T as frame_system::Config>::AccountId,
    description: Vec<u8>,
    name: Vec<u8>,
}

I tried to check if business exists add item if not show error:

    #[pallet::weight(10000)]
    #[transactional]
    pub fn add_item(
        origin: OriginFor<T>,
        store_id: [u8; 16],
        media: Vec<u8>,
        title: Vec<u8>,
        description: Vec<u8>,
        price: u32,
        count: u32,
    ) -> DispatchResult {
        let who = ensure_signed(origin)?;

        let item_id = Self::gen_dna();

        let item_info = BusinessItem {
            media: media.clone(),
            title: title.clone(),
            description: description.clone(),
            price: price.clone(),
            count: count.clone(),
            itemId: item_id,
        };

        Business::<T>::mutate(who.clone(), |store| -> DispatchResult {
            ensure!((Some(store.storeId) == Some(store_id)), <Error<T>>::StoreItemNotFound);
            let mut store_item_vec: Vec<BusinessItem> = Vec::new();
            store_item_vec.push(item_info);
            <Items<T>>::insert(item_id, who.clone(), store_item_vec);
            Ok(())
        });

        Self::deposit_event(Event::ItemCreated(Some(item_id)));

        Ok(())
    }

and this is Business Storage:

    #[pallet::storage]
#[pallet::getter(fn business)]
pub(super) type Business<T: Config> =
    StorageMap<_, Twox64Concat, T::AccountId, BusinessInfo<T>>;

1 Answer 1

3

Each storage item has a QueryKind set at declaration. This QueryKind defines the behavior/return value of functions like get and also mutate. There are currently three different query kinds defined in Substrate:

  • ValueQuery: Returns Default::default() if the value doesn't exist in the state or the value from the state.
  • OptionQuery Returns None if the value doesn't exist in the state or the value from the state wrapped in Some(_).
  • ResultQuery Returns Err(_) if the value doesn't exist in the state or the value from the state wrapped in Ok(_).

The default QueryKind is OptionQuery. In your example this would mean that your closure that you pass to mutate gets passed a &mut Option<BusinessInfo<T>>. So, writing:

Business::<T>::mutate(who.clone(), |store| -> DispatchResult {
    if let Some(store) = &mut store {
        let mut store_item_vec: Vec<BusinessItem> = Vec::new();
        store_item_vec.push(item_info);
        <Items<T>>::insert(item_id, who.clone(), store_item_vec);
        Ok(())
    } else {
        Err(<Error<T>>::StoreItemNotFound.into())
    }
});

Will fix your compile error.

Here you see some examples on how to declare the query kind.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.