"${element['price'] * element['step']} c"
always showing error
The operator '*' isn't defined for the type 'Object'.
The result must be multiplied two variables and convert to string.
What is wrong? I can not find any answer. Making as documentation says.
The element
is
var element = {
'title': 'Apple and more more thing',
'category': 'Fruit',
'description': 'Some data to describe',
'price': 24.67,
'bonus': '1% bonus',
'group': 'Picnik',
'step': 1.0
};
Dart is a static type safe language so before your code are even running, the code has been analyzed to be sure that there are no statically determined type issues.
In your example your have defined the following variable:
var element = {
'title': 'Apple and more more thing',
'category': 'Fruit',
'description': 'Some data to describe',
'price': 24.67,
'bonus': '1% bonus',
'group': 'Picnik',
'step': 1.0
};
By using var
your are telling Dart that it should automatically determine the type. This can also be done in this case. Dart will see that all the keys in the map are String
so we can safely assume the key type to be String
.
Then it looks at the values and tries to find a type which are common for all values. Since we have both double
and String
as values the type must be Object
since we cannot be more specific if we want a type which contain all values.
So the type of the map will be determined to be: Map<String, Object>
.
When you are then using the []
operator on the map it will be defined to return Object
from this map since this is the only thing we can be sure of.
But this is a problem when you try to do:
"${element['price'] * element['step']} c"
Since we in the analyzer phase can see we are going to call the *
operator on Object
the analyzer will then stop your program with a type error since what your are trying to do is not seen as type safe.
There are multiple ways to fix it which you can also see in other answers:
You can tell Dart "hey, I know what I am doing" and force Dart to use a specific type with:
"${(element['price'] as double) * (element['step'] as double)} c"
You can declare your map to contain dynamic
as value:
var element = <String, dynamic>{
'title': 'Apple and more more thing',
'category': 'Fruit',
'description': 'Some data to describe',
'price': 24.67,
'bonus': '1% bonus',
'group': 'Picnik',
'step': 1.0
};
This will remove all type safety of values in the map and you can then do anything you want with the values coming from the map without worrying about type issues by the analyzer. But the types will then be checked on runtime which can make your application crash if you gets the type wrong (like the type cast).
You should really not use Map
like you are doing. Instead, create a class:
void main() {
var element = Element(
title: 'Apple and more more thing',
category: 'Fruit',
description: 'Some data to describe',
price: 24.67,
bonus: '1% bonus',
group: 'Picnik',
step: 1.0);
print("${element.price * element.step} c"); // 24.67 c
}
class Element {
String title;
String category;
String description;
double price;
String bonus;
String group;
double step;
Element(
{this.title,
this.category,
this.description,
this.price,
this.bonus,
this.group,
this.step});
}
By doing so, you can ensure Dart know the type of each property and get type safety.