Product.fromJson constructor
Product.fromJson(
- Map<String, dynamic> json
)
Implementation
factory Product.fromJson(Map<String, dynamic> json) {
final Product result = _$ProductFromJson(json);
void setLanguageString(
final ProductField productField,
final OpenFoodFactsLanguage language,
final String label,
) {
switch (productField) {
case ProductField.NAME_IN_LANGUAGES:
case ProductField.NAME_ALL_LANGUAGES:
result.productNameInLanguages ??= {};
result.productNameInLanguages![language] = label;
break;
case ProductField.GENERIC_NAME_IN_LANGUAGES:
case ProductField.GENERIC_NAME_ALL_LANGUAGES:
result.genericNameInLanguages ??= {};
result.genericNameInLanguages![language] = label;
break;
case ProductField.ABBREVIATED_NAME_IN_LANGUAGES:
case ProductField.ABBREVIATED_NAME_ALL_LANGUAGES:
result.abbreviatedNameInLanguages ??= {};
result.abbreviatedNameInLanguages![language] = label;
break;
case ProductField.INGREDIENTS_TEXT_IN_LANGUAGES:
case ProductField.INGREDIENTS_TEXT_ALL_LANGUAGES:
result.ingredientsTextInLanguages ??= {};
result.ingredientsTextInLanguages![language] = label;
break;
case ProductField.PACKAGING_TEXT_IN_LANGUAGES:
case ProductField.PACKAGING_TEXT_ALL_LANGUAGES:
result.packagingTextInLanguages ??= {};
result.packagingTextInLanguages![language] = label;
break;
default:
// not supposed to be called with other ProductField values.
assert(false);
}
}
void setLanguageListString(
final ProductField productField,
final OpenFoodFactsLanguage language,
final Map<String, dynamic> json,
final String key,
) {
final List<String>? labels = _jsonValueToList(json[key]);
if (labels == null) {
return;
}
switch (productField) {
case ProductField.CATEGORIES_TAGS_IN_LANGUAGES:
result.categoriesTagsInLanguages ??= {};
result.categoriesTagsInLanguages![language] = labels;
break;
case ProductField.TRACES_TAGS_IN_LANGUAGES:
result.tracesTagsInLanguages ??= {};
result.tracesTagsInLanguages![language] = labels;
break;
case ProductField.BRANDS_TAGS_IN_LANGUAGES:
result.brandsTagsInLanguages ??= {};
result.brandsTagsInLanguages![language] = labels;
break;
case ProductField.STATES_TAGS_IN_LANGUAGES:
result.statesTagsInLanguages ??= {};
result.statesTagsInLanguages![language] = labels;
break;
case ProductField.STORES_TAGS_IN_LANGUAGES:
result.storesTagsInLanguages ??= {};
result.storesTagsInLanguages![language] = labels;
break;
case ProductField.MISC_TAGS_IN_LANGUAGES:
result.miscTagsInLanguages ??= {};
result.miscTagsInLanguages![language] = labels;
break;
case ProductField.INGREDIENTS_ANALYSIS_TAGS_IN_LANGUAGES:
result.ingredientsAnalysisTagsInLanguages ??= {};
result.ingredientsAnalysisTagsInLanguages![language] = labels;
break;
case ProductField.INGREDIENTS_TAGS_IN_LANGUAGES:
result.ingredientsTagsInLanguages ??= {};
result.ingredientsTagsInLanguages![language] = labels;
break;
case ProductField.LABELS_TAGS_IN_LANGUAGES:
result.labelsTagsInLanguages ??= {};
result.labelsTagsInLanguages![language] = labels;
break;
case ProductField.COUNTRIES_TAGS_IN_LANGUAGES:
result.countriesTagsInLanguages ??= {};
result.countriesTagsInLanguages![language] = labels;
break;
default:
// not supposed to be called with other ProductField values.
assert(false);
}
}
void addInLanguagesData(
final ProductField productField,
final OpenFoodFactsLanguage language,
final Map<String, dynamic> json,
final String key,
) {
switch (productField) {
case ProductField.NAME_IN_LANGUAGES:
case ProductField.GENERIC_NAME_IN_LANGUAGES:
case ProductField.ABBREVIATED_NAME_IN_LANGUAGES:
case ProductField.INGREDIENTS_TEXT_IN_LANGUAGES:
case ProductField.PACKAGING_TEXT_IN_LANGUAGES:
setLanguageString(productField, language, json[key]);
return;
case ProductField.CATEGORIES_TAGS_IN_LANGUAGES:
case ProductField.TRACES_TAGS_IN_LANGUAGES:
case ProductField.BRANDS_TAGS_IN_LANGUAGES:
case ProductField.STATES_TAGS_IN_LANGUAGES:
case ProductField.STORES_TAGS_IN_LANGUAGES:
case ProductField.MISC_TAGS_IN_LANGUAGES:
case ProductField.INGREDIENTS_ANALYSIS_TAGS_IN_LANGUAGES:
case ProductField.INGREDIENTS_TAGS_IN_LANGUAGES:
case ProductField.LABELS_TAGS_IN_LANGUAGES:
case ProductField.COUNTRIES_TAGS_IN_LANGUAGES:
setLanguageListString(productField, language, json, key);
return;
case ProductField.IMAGES_FRESHNESS_IN_LANGUAGES:
final Map<ImageField, int> values =
_jsonValueToImagesFreshness(json[key], language);
result.imagesFreshnessInLanguages ??= {};
result.imagesFreshnessInLanguages![language] = values;
return;
default:
if (fieldsInLanguages.contains(productField)) {
throw Exception('Unhandled in-languages case for $productField');
}
}
}
ProductField? extractProductField(
final String key,
final Iterable<ProductField> iterable,
) {
for (final ProductField productField in iterable) {
if (key.startsWith(productField.offTag)) {
return productField;
}
}
return null;
}
for (final String key in json.keys) {
if (key.contains('debug')) {
continue;
}
// If the JSON contained *_in_languages fields,
// _$ProductFromJson(json) already decoded them
if (key.endsWith('_in_languages')) {
continue;
}
// The OFF API can give values in all available languages for some
// of the fields ('product_name_languages'), and in a requested list of
// languages for an additional number of fields
// (`product_name_[2 letter language code]`).
// We store those values in a more structured maps like
// [productNameInLanguages].
ProductField? productField = extractProductField(key, fieldsAllLanguages);
if (productField != null) {
final Map<OpenFoodFactsLanguage, String>? localized =
_getLocalizedStrings(json[key]);
if (localized != null) {
for (final MapEntry<OpenFoodFactsLanguage, String> entry
in localized.entries) {
setLanguageString(productField, entry.key, entry.value);
}
}
continue;
}
productField = extractProductField(key, fieldsInLanguages);
if (productField != null) {
final OpenFoodFactsLanguage language =
_langFrom(key, productField.offTag);
if (language != OpenFoodFactsLanguage.UNDEFINED) {
addInLanguagesData(productField, language, json, key);
}
continue;
}
}
return result;
}