Access Element in List by Index - dart

I'm getting this error while trying to access element in a List .
This is my code :
List<TextEditingController> controllers = [];
void _addCardWidgetExp() {
setState(() {
widget.controllers.add(TextEditingController());
widget.controllers.add(TextEditingController());
widget.controllers.add(TextEditingController());
widget.controllers.add(TextEditingController());
_cardList.add(SizedBox(height: 10));
Divider(
thickness: 2,
color: Colors.white,
);
_cardList.add(InputRefNomProduit(
fieldController: widget.controllers.first,
fieldController2: widget.controllers.[1],
fieldController3: widget.controllers.[2],
fieldController4: widget.controllers.last,
));
});
}
I'm getting the following error :
The getter '[' isn't defined for the type 'List<TextEditingController>'.
Try importing the library that defines '[', correcting the name to the name of an existing getter, or defining a getter or field named '['.
ps: the error is only on these two lines :
fieldController2: widget.controllers.[1],
fieldController3: widget.controllers.[2],

Related

Why does this `.new` constructor auto increment a field?

I'm trying to port some Dart code to another language but I'm a little confused by the .new constructor.
Given this class:
class DynamicTreeNode {
final int id;
DynamicTreeNode(this.id);
}
and this simple main function:
void main(List<String> arguments) {
List<DynamicTreeNode> _nodes = List<DynamicTreeNode>.generate(
16,
DynamicTreeNode.new,
);
}
I can see in the debugger that each instance of DynamicTreeNode is given an incrementing id value matching the index in the List:
Can someone explain what is happening here? I thought the call to new would fail as the unnamed (and only constructor) requires an int to be passed to it.
If we look at the List.generate constructor we can see that the signature is
List<E>.generate(
int length,
E generator(
int index
),
{bool growable = true}
)
The generator parameter — in your case DynamicTreeNode.new — is a function that takes the position in the list it is generated into as an argument and returns the type of element of the list. So the first DynamicTreeNode in the list will be generated by DynamicTreeNode.new(0), the second one as DynamicTreeNode.new(1), etc.
I'm not familiar with dart at all, but it looks like you're passing the .new function itself, and the .generate function on List<T> will construct an object under the hood by calling the .new function with an incrementing integer.
In JavaScript, that would look like this:
class DynamicTreeNode {
constructor(id) {
this.id = id;
}
}
const generate = (len, constructor) => new Array(len).fill(0).map((_, idx) => new constructor(idx));
function main() {
const _nodes = generate(16, DynamicTreeNode);
console.log(_nodes);
}
main();

React-query FC cannot be used as a JSX component, missing properties from Element type

I'm trying to implement useQuery to return the number (.length) of records I have of a given model, in this case, properties.
async function fetchProperties(): Promise<Property[]> {
return axios
.get("http://127.0.0.1:3000/api/v1/properties")
.then((res) => res.data);
}
export default function UsePropertiesCount() {
return useQuery<Property[], Error, number>("properties", fetchProperties, {
select: (properties: Property[]) => properties.length,
});
}
I get the following error:
'UsePropertiesCount' cannot be used as a JSX component.
Its return type 'UseQueryResult<number, Error>' is not a valid JSX element.
Type 'QueryObserverIdleResult<number, Error>' is missing the following properties from type 'Element': type, props, key
I'm not sure what I'm doing incorrectly, since I've followed this example
When I saved the query to a variable and returned it with result.data it worked
const result = useQuery<Property[], Error, number>(
"properties",
fetchProperties,
{
select: (properties: Property[]) => properties.length,
}
);
return <>{result.data}</>;

Fat Arrow notation with curly braces in setState Dart/Flutter

I am very new to Dart/Flutter and I have a confusion regarding the => notation. The documentation says that the => notation is used as a shorthand to return a single expression.
bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;
My doubt comes when I am trying to set state in a flutter application.
RaisedButton(
onPressed: () => {
setState(() {
print('hello');
_products.add('More stuff');
})
},
child: Text('Add Product'),
),
Now when i change the setState method with => notation
RaisedButton(
onPressed: () => {
setState(() => {
print('hello'),
_products.add('More stuff'),
})
},
child: Text('Add Product'),
),
Both methods mentioned above work, that is they set the state as expected. All i had to do was change the semicolons to commas when using the fat arrow notation.
What is the logic behind this ? How is the fat arrow notation working with curly braces which contains multiple expressions within it.
Edit
As mentioned by Hemanth Raj the => returns a set and the code segment containing the => notation can be written as follows.
RaisedButton(
onPressed: () => {
setState(() {
return {
print('hello'),
_products.add('More stuff'),
};
})
},
child: Text('Add Product'),
),
How is the returned set containing a print function and _products.add actually updating the state. Shouldn't it throw some kind of error because usually setState is done by an expression such as _products.add('More stuff');.
This is one of the interesting questions that I would love to answer.
As the official documents say here, yes => is used as a shorthand syntax to { return ... } which means => will just return whatever is produced on the righthand side.
Also from Dart 2.2 and above, a Set can be defined with comma separated values enclosed in a {} as mentioned in docs here.
Hence, the syntax you are using, i.e {} with statements separated with a comma, it is treated as a Set by the => functions. Each element being a function call, () => { f(a) , f(b), g(a),} would return a Set with the elements returned by each function call.
This example might help you understand what is happening under the hood:
dynamic reflect(dynamic a){
return a;
}
void main() {
Function shortHand = () => {reflect(1),reflect('a'),reflect({}),reflect([]),}; // this function when called will return a Set<dynamic>
print(shortHand().runtimeType); // will print `_LinkedHashSet<dynamic>`
}
So the syntax
() => '...' returns a String,
() => [ ... , ..., ...] returns a List
and similarly () => { ... , ... , ... } actually returns a Set
Note: This method of returning set with comma separated function calls is not recommended, would request you also not to use it unless you wanted a Set to be returned as result
Reply to the Edit :
Let me breakdown the function call and results for you. So your code goes like this,
() => {
setState(() {
return {
print('hello'),
_products.add('More stuff'),
};
})
}
Here the => returns a Set with the result of setState, i.e it'll return { (result of setState call) } which might be { null }
As you have call setState the below code gets executed, which again returns a Set with { (result of print), (result of _product.add), }
() {
return {
print('hello'),
_products.add('More stuff'),
};
}
State will update, as you are executing _products.add('More stuff'), where 'More stuff' will be added to _products irrespective of where you call it. When setState is being called, the widget will be rebuilt with the _products with new data added.
Hope this helped!
For the record, the recommended syntax for what you are doing is:
RaisedButton(
onPressed: () {
setState(() {
print('hello');
_products.add('More stuff');
});
},
child: Text('Add Product'),
),
The syntax (args) => { statements } is not how Dart writes function bodies, you do either (args) { statements } or (args) => singleExpression.
Also, you need to terminate statements with semicolons, ;, not commas.
As others have pointed out, the syntax you use (args) => { print("something"), somethingElse } is actually creating a set (a Set<void> because the return type of print is void) and returning that.
This is a perfect storm of small syntax mistakes, which would seem reasonable to a JavaScript programmer, that comes together to actually mean something completely different in Dart.
And, just to make things even worse, the code works. The set literal will evaluate its expression in order, and nobody sees the created set anyway. The syntax just doesn't generalize — you can't change any of the expressions to, say, a for-loop (yet, you will be able to in the next version of Dart).
So, in Dart, never use => { unless you want to return a set or map.

Flutter (dart) ListView Builder Widget giving Invalid Arguments Error

So, I have created a basic map
var tracks = const [
{
'title':'Something',
'subtitle':'Something'
},
{
'title':'Something Else',
},
{
'title':'Admission',
},
{
'title':'University',
},
{
'title':'Exam',
'subtitle':'Something'
},
{
'title':'Job',
},
];
And this is being called by a ListView.builder in the following manner:
var trackTitles = tracks[index];
and then being used like this:
return PrimaryMail(
title: trackTitles['titles'],
)
But, it is throwing an "Invalid Argument(s): titles error in the final build. No dart-analytics issues seen. The only error I see (info, not serious) is This class (or a class which this class inherits from) is marked as '#immutable', but one or more of its instance fields are not final: Home.tracks (must_be_immutable] lib\main.dart:18). [edit: the immutable issue has been fixed now by replacing var with final, but the original problem remains]
So, any way to understand why it is throwing an invalid argument even though the title key does exist?
The full code of this page is here.
Add final before the field you declare in line lib\main.dart:18
If you have var there, replace var by final

firing a CustomEvent in Polymer gives me "Exception: Class 'MyData' has no instance method '[]'"

class MyData {
String name;
String age;
MyData(this.name, this.age);
}
...
class AlertSimulatorElement extends PolymerElement {
void handleClick(e,d,t) {
asyncFire('polymer-signal',detail: new MyData("Mike",99));
// this works:
//asyncFire('polymer-signal', detail: {'name': "foo", 'data': "Foo!"});
}
}
asynFire gives me:
Exception: Class 'MyData' has no instance method '[]'.
NoSuchMethodError : method not found: '[]'
Receiver: Instance of 'MyData'
Arguments: ["name"]
I'm using Chromium Version 33.0.1750.48 (251129) and polymer 0.9.5
The Doc says I can use Object but this seems to be wrong? Any hints?
PolymerElement#fire: http://goo.gl/DYXMiZ
thx
Günter pointed my in the right direction - it is *a bug in polymer_signals.dart*
polymer_signals.dart (Line 49)
#initMethod
void registerListener() {
// signal listener at document
document.addEventListener('polymer-signal', (e) {
_notify(e.detail['name'], e.detail['data']);
});
}
As a workaround for now:
// (sender.dart)
asyncFire('polymer-signal',detail: { 'name' : "alertevent", 'data' : new MyData("Mike",47) });
// (receiver.html)
<polymer-element name="mm-alert-list" on-add-alert-event="{{handleAddAlert}}">
...
<polymer-signals on-polymer-signal-alertevent="{{fooSignal}}"></polymer-signals>
</polymer-element>
// (receiver.dart)
...
#CustomTag('mm-alert-list')
class AlertListElement extends PolymerElement {
...
fooSignal(final CustomEvent event, detail, sender){
print('<br>[my-app] got a [' + detail.name + '] signal<br>');
}
...
}
});
[Update]
Filed a bug: https://github.com/ErikGrimes/polymer_elements/issues/143
There was a limitation that only primitive types (String, int, double), List, Map or a List or a Map of on of them was allowed for event details. I thought this limitation was gone some months ago but maybe it came back.
EDIT
I just tried it without Polymer and it worked
var b = dom.querySelector('#button');
b.onClick.listen((e) {
b.dispatchEvent(new dom.CustomEvent('polymer-signal',detail: new MyData("Mike","99")));
});
This should also work if you use this (your Polymer element) instead of b.

Resources