Kosmetika
Kosmetika

Reputation: 21304

Bacon.js (FRP) - Add/remove values from array and save in storage

I'm new to Bacon.js and FRP concepts. I'm struggling with implementing very basic functionality. I have an array of saved values in some local storage:

['A', 'B', 'C']

I have an asynchronous function that reads these values from storage (returns Promise).

I have 'add' event to add new item to array and 'remove' event to remove item from array. Every array update should write down updated array into the local storage.

I ended up with this solution but it doesn't work as expected:

const items = Bacon
    .fromPromise(storage.get('items'))
    .mapError(() => [])
    .merge(Bacon.fromEvent(events, 'add').map(l => [l]))
    .merge(Bacon.fromEvent(events, 'remove').map(l => [l]))
    .skipDuplicates()
    .filter(l => l)
    .toProperty();

items.onValue((items) => {
    // everytime rewrites storage with new array (but without old values)
    console.log(items); 
    storage.put('items', items);
 });

return items;

So at the start behavior is:

How I can do it with Bacon? I was thinking of update method but unfortunately initial value of it should be not a stream or some other async action.

Upvotes: 1

Views: 254

Answers (1)

raimohanska
raimohanska

Reputation: 3405

Use Bacon.update. You can use an empty array as the initial value and provide the async initial value from your storage as one of the input streams for Bacon.update. So, try something like

const items = Bacon.update([],
  Bacon.fromPromise(storage.get('items')), (_, items) => items,
  Bacon.fromEvent(events, 'add'), (items, newItem) => items.concat(newItem),
  Bacon.fromEvent(events, 'remove'), (items, removedItem) => 
    items.filter((item) => item != removedItem)
)

Upvotes: 2

Related Questions