Skip to content

context.read(providerref) doesn't give same reference of stateNotifierProvider when call from two different functions of a Widget #849

@jimi1977

Description

@jimi1977

Hi,

I am setting values of variables declared in View Model class which is a StateNotifier, inside a function of widget. When I try to access the values of those variables from a different function of same widget, their values are null. I have debugged code to verify that first function is setting values correctly.
It works fine when I convert StateNotifier to ChangeNotifier. I am not sure what I am doing wrong or may be my code is structured wrong.

Here is cutdown version of my StateNotifier

`class ProductViewModel extends StateNotifier {
String errorMessage;

Product product;

final ProductService productService;
final CategoryService categoryService;
final BrandService brandService;
final TranslatorService translatorService;
final ProductOptionsViewModel productOptionsViewModel;
final ProductVariantViewModel productVariantViewModel;

ProductViewModel(this.productService, this.categoryService, this.brandService, this.translatorService,
this.productOptionsViewModel, this.productVariantViewModel)
: super(ProductInitial());

String productId;
List _sizes;
String _selectedBrand;
String _selectedCategory;
String _selectedStore;
String _productName;
String _productIntlName;
String _sku;

String get selectedBrand => _selectedBrand;

set selectedBrand(String value) {
_selectedBrand = value;
}

String get selectedCategory => _selectedCategory;

set selectedCategory(String value) {
_selectedCategory = value;
}

String get selectedStore => _selectedStore;

set selectedStore(String value) {
_selectedStore = value;
}

String get productName => _productName;

set productName(String value) {
_productName = value;
}

String get productIntlName => _productIntlName;

set productIntlName(String value) {
_productIntlName = value;
}

String get sku => _sku;

set sku(String value) {
_sku = value;
}

Future saveProductDetails() async {
bool isSave = false;
bool imageSaved = await saveProductImage();
if (!imageSaved) return imageSaved;
List searchKeywords = indexProductName(_productName);
List searchTag1 = _searchTag1 != null ? indexProductName(_searchTag1) : null;
List searchTag2 = _searchTag2 != null ? indexProductName(_searchTag2) : null;
List searchTag3 = _searchTag3 != null ? indexProductName(_searchTag3) : null;
if (deal != null && _dealsAddedDateTime == null) {
_dealsAddedDateTime = DateTime.now();
}
print(productOptionsViewModel.toString());

Product _product = Product(
    productId: productId,
    name: _productName,
    intlName: _productIntlName,
    category: FirebaseFirestore.instance.doc(_selectedCategory),
    brand: FirebaseFirestore.instance.doc(_selectedBrand),
    sku: _sku,
    quantity: _quantity,
    price: _price,
    containSizes: productOptionsViewModel.sizes,
    containColors: productOptionsViewModel.colors,
    accessory: productOptionsViewModel.accessory ,
    salesTaxApplicable: productOptionsViewModel.salesTax,
);

isSave = await productService.saveProduct(_product);
if (!isSave) {
  errorMessage = "Error in saving product information";
} else {
  productId = productService.newProductId;
}

return isSave;

}
}StateNotifierProvider declarationfinal productViewModelProvider = StateNotifierProvider.autoDispose<ProductViewModel,ProductState>((ref) => ProductViewModel(
ref.watch(productServiceProvider),
ref.watch(categoryServiceProvider),
ref.watch(brandServiceProvider),
ref.watch(translatorServiceProvider),
ref.watch(productOptionsViewModelProvider),
ref.watch(productVariantViewModelProvider)));`

UI Functions that set values in StateNorifier.
` Future validateProduct() async {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
final model = context.read(productViewModelProvider.notifier);
final storeViewModel = context.read(storeViewModelProvider.notifier);
var _store = await storeViewModel.getMyStore();
model.productName = _productName;
model.productIntlName = _productIntlName;
model.sku = _sku;
model.quantity = _quantity;
model.price = _price;
model.selectedBrand = _selectedBrand;
model.selectedCategory = _selectedCategory;
model.selectedStore = _storeCode;
model.description = _productDescription;
model.manufacturerLink = _manufacturerLink;
model.searchTag1 = _searchTag1;
model.searchTag2 = _searchTag2;
model.searchTag3 = _searchTag3;
if (model.addedDateTime == null) {
model.addedDateTime = DateTime.now();
}
if (_storeCode == null) {
_storeCode = _store.store;
}
if (model.selectedStore == null) {
model.selectedStore = _storeCode;
}
return true;
}
else return false;
}

Future saveProductDetails() async {
final model = context.read(productViewModelProvider.notifier);

bool isProductSaved = await model.saveProductDetails();
if (isProductSaved) {
  if (_isProductExist) {
    displayMessage(context, "Product Information Updated");
  } else
    displayMessage(context, "Product Information Saved");

  _formSaved = true;
  isFormChanged = false;
  return true;
} else if (isProductSaved == false) {
  _formSaved = false;
  displayMessage(context, model.errorMessage);
}

return isProductSaved;

}`

State
`abstract class ProductState {
const ProductState();
}

class ProductInitial extends ProductState {
const ProductInitial();
}

class ProductLoading extends ProductState {
const ProductLoading();
}

class ProductLoaded extends ProductState {
final Product product;

ProductLoaded(this.product);

@OverRide
bool operator ==(Object other) =>
identical(this, other) || other is ProductLoaded && runtimeType == other.runtimeType && product == other.product;

@OverRide
int get hashCode => product.hashCode;
}

class ProductSaving extends ProductState {
const ProductSaving();
}

class ProductSaved extends ProductState {
final Product product;

ProductSaved(this.product);

@OverRide
bool operator ==(Object other) =>
identical(this, other) || other is ProductSaved && runtimeType == other.runtimeType && product == other.product;

@OverRide
int get hashCode => product.hashCode;
}

class ProductError extends ProductState {
final String errorMessage;

ProductError(this.errorMessage);
}`

Regards,

Jamal

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions