class Volt::QueryListener

The query listener is what gets notified on the backend when the results from a query have changed. It then will make the necessary changes to any ArrayStore's to get them to display the new data.

Attributes

listening[R]

Public Class Methods

new(query_listener_pool, tasks, collection, query) click to toggle source
# File lib/volt/models/persistors/query/query_listener.rb, line 8
def initialize(query_listener_pool, tasks, collection, query)
  @query_listener_pool = query_listener_pool
  @tasks               = tasks
  @stores              = []

  @collection = collection
  @query      = query

  @listening = false
end

Public Instance Methods

add_listener() click to toggle source
# File lib/volt/models/persistors/query/query_listener.rb, line 19
def add_listener
  @listening = true

  # Call the backend and add the listner
  QueryTasks.add_listener(@collection, @query).then do |ret|
    results, errors = ret

    # When the initial data comes back, add it into the stores.
    @stores.dup.each do |store|
      # Clear if there are existing items
      Volt.run_in_mode(:no_model_promises) do
        store.model.clear if store.model.size > 0
      end

      results.each do |index, data|
        store.add(index, data)
      end

      store.model.change_state_to(:loaded_state, :loaded)

      # if Volt.server?
      #   store.model.change_state_to(:loaded_state, :dirty)
      # end
    end
  end.fail do |err|
    # TODO: need to make it so we can re-raise out of this promise
    msg = "Error adding listener: #{err.inspect}"
    msg += "\n#{err.backtrace.join("\n")}" if err.respond_to?(:backtrace)
    Volt.logger.error(msg)

    # If we get back that the user signature is wrong, log the user out.
    if err.start_with?('VoltUserError:')
      # Delete the invalid cookie
      Volt.current_app.cookies.delete(:user_id)
    end

    fail err
  end
end
add_store(store, &block) click to toggle source
# File lib/volt/models/persistors/query/query_listener.rb, line 59
def add_store(store, &block)
  @stores << store

  if @listening
    # We are already listening and have this model somewhere else,
    # copy the data from the existing model.
    store.model.clear

    # Get an existing store to copy data from
    first_store_model = @stores.first.model
    first_store_model.each_with_index do |item, index|
      store.add(index, item.to_h)
    end

    store.model.change_state_to(:loaded_state, first_store_model.loaded_state)
  else
    # First time we've added a store, setup the listener and get
    # the initial data.
    add_listener
  end
end
added(index, data) click to toggle source
# File lib/volt/models/persistors/query/query_listener.rb, line 97
def added(index, data)
  @stores.each do |store|
    store.add(index, data)
  end
end
changed(model_id, data) click to toggle source
# File lib/volt/models/persistors/query/query_listener.rb, line 109
def changed(model_id, data)
  $loading_models = true
  Persistors::ModelStore.changed(model_id, data)
  $loading_models = false
end
remove_store(store) click to toggle source
# File lib/volt/models/persistors/query/query_listener.rb, line 81
def remove_store(store)
  @stores.delete(store)

  # When there are no stores left, remove the query listener from
  # the pool, it can get created again later.
  if @stores.size == 0
    @query_listener_pool.remove(@collection, @query)

    # Stop listening
    if @listening
      @listening = false
      QueryTasks.remove_listener(@collection, @query)
    end
  end
end
removed(ids) click to toggle source
# File lib/volt/models/persistors/query/query_listener.rb, line 103
def removed(ids)
  @stores.each do |store|
    store.remove(ids)
  end
end