Invoke POST operation in different parts of app, by utilising factory generated functions from a service

Viewed 16

I'm setting up something to persist data on individual events that occur within a user 'transaction' (session) within an application.

I'm creating something that allows a different POST operation for each event, with a generic method of posting, that uses different payloads for each event. I want to be able to record events in different parts of the application by importing a collection of operations from a service, then invoking different operations within the collection.

I'm posting what I've done so far. transactionEvents is created using a factory pattern, through calling the function makeTransactionEvents.

How can I can call the userPressedButton POST operation in myRoute.svelte?

service.js

/**
 * Performs the equivalent of Array.prototype.map() on an object.
 *
 * @param {object} obj - The object to map.
 * @param {Function} func - The function to execute on each item in the object.
 * @returns {object} The new object resulting from the map.
 */
function objectMap(obj, func) {
  return Object.fromEntries(
    Object.entries(obj).map(([key, value], index) => [
      key,
      func(value, key, index),
    ])
  );
}

const eventPayloads = {

  userPressedButton() {
    return {
      eventType: TRANSACTION_EVENT_TYPES.UserAction,
      eventSubType: TRANSACTION_EVENT_SUBTYPES.PressedButton
    }
  },

  userDidSomethingElse() {
    return {
      eventType: TRANSACTION_EVENT_TYPES.UserAction,
      eventSubType: TRANSACTION_EVENT_SUBTYPES.DidSomethingElse
    }
  }
};

/**
 * Create a 'transactionEvent' service call function.
 *
 * Sends the request.
 *
 * @param {Function} payloadFunc - Function for creating the payload.
 * @returns {Function} - Initialises creation of TransactionEvent.
 */
function makeTransactionEvent(payloadFunc) {
  return (...args) => {
    initialiseTransactionEvent(payloadFunc(...args));
  };
}

/**
 * Creates functions for each of the reporting transactionEvent payloads.
 */
function makeTransactionEvents() {
  return objectMap(eventPayloads, (payloadFunc) => makeTransactionEvent(payloadFunc));
}

function initialiseTransactionEvent(body) {
  logger.info(`Recording transaction event.`);
  fetch(myUri, {
    method: 'POST',
    .... other http stuff
    body: JSON.stringify(body),
  })
}

const transactionEvents = makeTransactionEvents();

export default {
  ...transactionEvents,
}

myRoute.svelte

import { transactionEvents } from 'service.js';

** How do I call userPressedButton() by referencing its key within transactionEvents ? **
1 Answers

I realised that the spread transactionEvents is being exported as a constant which represents the default. With name independence of namespacing for an import, I can reference the constant in myRoute.svelte like this:

import dataPersister from 'service.js';

Then simply call userPressedButton() with:

dataPersister.userPressedButton()
Related