reactivemarbles / DynamicData

Reactive collections based on Rx.Net
http://dynamic-data.org
MIT License
1.73k stars 182 forks source link

Need to wait for Transform() to complete. #209

Closed BenWhite27 closed 5 years ago

BenWhite27 commented 5 years ago

I have the following code that uses a Transform() to create a bindable collection, a user can invoke a command to create a new Customer and I need to be able to assign the Transformed ViewModel to a SelectedCustomer property so the user can fill in the details.

The issue is my Transformed collection doesn't contain the item yet and I haven't found a way to await or be notified for this to happen. I've tried the forceRefresh parameter on Transform() but this also seems to be asynchronous like AddOrUpdate().

//
// Class init
//
SourceCache<Customer, int> customersCache = new SourceCache<Customer, int>(c=>c.Id);
ReadOnlyObservableCollection<CustomerViewModel> Customers { get; set;} // Backed by 'customers' field
CustomerViewModel SelectedCustomer { get; set; }

customersCache.Connect().Transform(c=> new CustomerViewModel(c)).Bind(out customers).Subscribe();

//
// Start of 'New Customer Command' code.
//
var newCustomer = new Customer();
customersCache.AddOrUpdate(newCustomer);

// Code fails here because the transformed collection doesn't yet contain the new customer.
selectedCustomer = Customers.Single(c=>c.Id == newCustomer.Id);

The code above is for reference but abbreviated.

Am I missing something or do I need to rethink the how this is done? I can make it work by adding a delay in the code but not keen on that solution.

modplug commented 5 years ago

You can use the OnItemAdded operator to get the latest added item

           var transformedItems = sourceCache.Connect()
                .Transform(i => yourobject)
                .Publish();

            transformedItems.OnItemAdded(i => SelectedItem = i)
                .Subscribe();

            transformedItems
                .Bind(out _items)
                .Subscribe();

            transformedItems.Connect();
RolandPheasant commented 5 years ago

Good answer @modplug. I was in the process of dong a example using Watch when you posted this. The funny thing is your solution is better than mine.

Example in SelectCacheItem.cs with unit test

BenWhite27 commented 5 years ago

Thank you both for the answers looks like both of them will work, I actually prefer the Watch option for my scenario here but reckon I'll end up using both at some point soon.

Great library @RolandPheasant, my thanks to you and all the contributors.