Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "builtAt" to builders #83

Open
davidmorgan opened this issue Dec 1, 2016 · 16 comments
Open

Add "builtAt" to builders #83

davidmorgan opened this issue Dec 1, 2016 · 16 comments
Assignees

Comments

@davidmorgan
Copy link
Contributor

ListBuilder could for example have a "builtAt" method that converts the value at the specified index to a builder, similar to the "rebuild" method but for an element in the collection:

var list = new BuiltList<BuiltList>([new BuiltList[1]]);
var rebuiltList = list.rebuild((b) => b.rebuildAt(0).add(2));

--> [[1, 2]]

This should work for nested built collections and for built values.

@sroddy
Copy link

sroddy commented Feb 8, 2018

any hope for having this implemented any time soon? :)

@davidmorgan
Copy link
Contributor Author

Last I looked at this, it required a lot of boilerplate to make it work--because you have to tell the collection the type of the builder that it needs to expose.

It's possible that with Dart 2's type inference this can be workable. I'll take a look again sometime. But probably not very soon ;) ... the next changes for built_collection will be improvements related to Dart 2.

@neckaros
Copy link

neckaros commented Jan 2, 2020

Any news on this?

@davidmorgan
Copy link
Contributor Author

It's actually possible to do this with extension methods now :)

I've been waiting to see how the simpler extension methods (build, toBuiltList, toBuiltSet, toBuiltMap) are received. They seem to have gone smoothly.

@brandondiamond
Copy link

Another enthusiastic dev -- this would clean up a bunch of my code.

@davidmorgan
Copy link
Contributor Author

You can actually do this yourself now using extension methods :) I've explored adding them, but didn't get around to a final answer yet. If you try it I'd be interested to hear how it goes :)

Something like this:

extension BuiltValueListBuilderExtension<V extends Built<V, B>,
    B extends Builder> on ListBuilder<Built<V, B>> {
  void rebuildAt(int index, void Function(B) updates) =>
      this[index] = this[index].rebuild(updates);
}

extension BuiltValueMapBuilderExtension<K, V extends Built<V, B>,
    B extends Builder> on MapBuilder<K, Built<V, B>> {
  void rebuildAt(K key, void Function(B) updates) =>
      this[key] = this[key].rebuild(updates);
}

@neckaros
Copy link

Thanks!
here is the slightly modified working version:

extension BuiltValueListBuilderExtension<V extends Built<V, B>,
    B extends Builder<V, B>> on ListBuilder<Built<V, B>> {
  void rebuildAt(int index, void Function(B) updates) =>
      this[index] = this[index].rebuild(updates);
}

extension BuiltValueMapBuilderExtension<K, V extends Built<V, B>,
    B extends Builder<V, B>> on MapBuilder<K, Built<V, B>> {
  void rebuildAt(K key, void Function(B) updates) =>
      this[key] = this[key].rebuild(updates);
}

i'm trying to do a rebuildWhere as it would greatly reduce the number of line of code in my async "Bloc" update process (need to get the current index often to avoid edition of the wrong index if list changed). but i don't see how yet. will post back here if find a way. But since ListBuilder doesn't expose indexWhere it won't be easy i think :)

@davidmorgan
Copy link
Contributor Author

How about something like

for (var i = 0; i != this.length; ++i) {
  if (condition(this[i])) this[i] = this[i].rebuild(updates);
}

?

@neckaros
Copy link

So simple yet working 👍

Thanks!!!

@kushvatsa
Copy link

kushvatsa commented Apr 25, 2020

Hey @davidmorgan , rebuildAt working 👍 . Thank you!!

@shubhamtanwar23
Copy link

shubhamtanwar23 commented Apr 25, 2020

@kushvatsa I think this will work

extension BuiltValueListBuilderExtension<V extends Built<V, B>,
    B extends Builder<V, B>> on ListBuilder<Built<V, B>> {

  void rebuildWhere(bool Function(V) test, void Function(B) updates) {
    for (var i = 0; i != this.length; ++i) {
      if (test(this[i])) this[i] = this[i].rebuild(updates);
    }
  }
}

@kushvatsa
Copy link

It works @shubhamtanwar23 , Thank you 👍

@smkhalsa
Copy link

smkhalsa commented Aug 4, 2020

@davidmorgan is there anything preventing one of the above solutions from being merged in?

@davidmorgan
Copy link
Contributor Author

@smkhalsa Nothing specific :) I'm a little hesitant about adding extension methods, since they're new, and once they're added it's a breaking API change to change them. Also, it's easy to roll your own :D

I'll look at adding these in a coming release.

@arlucio
Copy link

arlucio commented Sep 1, 2020

How do I use these extension methods?

I'm trying to use them but I'm not sure where to add them so that they are recognized.

Tried to use it like I use any other extension methods: Creating a file with them and trying to import that file whenever I need to use the methods (like below), but they are not recognized.

import 'package:built_collection/built_collection.dart';
import 'package:built_value/built_value.dart';

extension BuiltValueListBuilderExtension<V extends Built<V, B>, B extends Builder<V, B>> on ListBuilder<Built<V, B>> {
  void rebuildAt(int index, void Function(B) updates) => this[index] = this[index].rebuild(updates);
}

var list = BuiltList<BuiltList>([BuiltList.from([1])]);
var rebuiltList = list.rebuild((b) => b.rebuildAt(0).add(2));

In this "rebuildAt" is not recognized as an option. How to use this?

@davidmorgan
Copy link
Contributor Author

You're calling

rebuildAt(0).add(2)

it should be

rebuildAt(0, (b) => b..add(2))

:)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants