FAQ #2 - How to get a list of events?

You can query Flow for a list of events in a specific range by creating following helper method:

const getEvents = async (params) => {
  // Define event type from params
  const { contractAddress, contractName, eventName } = params;
  const eventType = `A.${contractAddress}.${contractName}.${eventName}`;

  const { from = 0, to } = params;
  let toBlock;
  if (to === undefined) {
    // Get latest block
    const blockResponse = await fcl.send(
      await sdk.build([sdk.getLatestBlock()])
    );
    toBlock = blockResponse.latestBlock.height;
  } else {
    toBlock = to;
  }

  const response = await fcl.send(
    await sdk.build([sdk.getEvents(eventType, from, toBlock)])
  );

  // Return a list of events
  return response.events;
};

And then use it, for example, like this:

const getHelloEvents = async () => {
  const events = await getEvents({
    contractName: "HelloWorld",
    contractAddress: "01cf0e2f2f715450", // note the address is without "0x" prefix
    eventName: "CustomEvent",
  });
  console.log({ events });
};

I’ve also updated the repository, which this method and others to help you deploy contract, send transactions and execute scripts on Flow. You can reference it here:

2 Likes

Hey @MaxStarka ! :wave:
I tried creating a custom event on my own.

event_error1.png

However, I’m facing this problem as can be seen below -
value[0].name should be “id” not “ethid”
value[1].name should be “ethid” not “id”

event_error2

Any guesses what’s wrong with my code?

All cool with your code, @jayesh_wayesh. It’s a known error that arguments are alphabetically sorted. The team is working on it :grimacing:

As a temporary solution, in your Cadence code for event declaration, add prefixes a_, b_, etc. like this (don’t forget to update the signature, when you emit them :wink:)

pub event Converted(a_id: UInt64, b_ethid: String)

Create a helper method:

export const fixNames = (item) => {
  var result = {}

  for (let name of Object.keys(item)) {
    const value = item[name]
    const fixedName = name.replace(/\w+_/,'')
    result[fixedName] = value
  }

  return result
}

And your method for requesting events :

const getEvents = async (params) => {
  // Define event type from params
  const { contractAddress, contractName, eventName } = params;
  const eventType = `A.${contractAddress}.${contractName}.${eventName}`;

  const { from = 0, to } = params;
  let toBlock;
  if (to === undefined) {
    // Get latest block
    const blockResponse = await fcl.send(
      await sdk.build([sdk.getLatestBlock()])
    );
    toBlock = blockResponse.latestBlock.height;
  } else {
    toBlock = to;
  }

  const response = await fcl.send(
    await sdk.build([sdk.getEvents(eventType, from, toBlock)])
  );

  // Decode server response, so we could get properly formatted values
  const events = await fcl.decode(response);

  // Now let's purge prefixes from names
  const fixedEvents = events.map((item) => {
    const { data } = item;
    item.data = fixNames(data);
    return item;
  });

  // Return a list of events
  return fixedEvents;
};

This way you will be able to utilize fcl.decode method and later you can redeploy the code without prefixes and it should (theoretically) still work without updating your Javascript code :wink:

2 Likes

Thanks @MaxStarka :raised_hands:

Hello @MaxStarka,
I have just started using flow blockchain and trying to listen to event.
I have tried the code that you have mentioned and it gives me error “err Error: failed to get events: could not look up block: key not found”

can you please point what am i doing wrong? i tried with “0x” prefix and also without that

const events = await getEvents({

  contractName: "TopShot",

  contractAddress: "0b2a3299cc857e29", // note the address is without "0x" prefix

  eventName: "PlayAddedToSet",

});