Bird
Raised Fist0
Blockchain / Solidityprogramming~10 mins

Listening to events on frontend in Blockchain / Solidity - Step-by-Step Execution

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Concept Flow - Listening to events on frontend
Connect to blockchain provider
Get contract instance with ABI & address
Set up event listener on contract
Wait for event emission
Event received -> execute callback
Update UI or state with event data
End or repeat
The frontend connects to the blockchain, listens for contract events, and updates the UI when events happen.
Execution Sample
Blockchain / Solidity
const contract = new ethers.Contract(address, abi, provider);
contract.on('Transfer', (from, to, amount) => {
  console.log(`Transfer from ${from} to ${to} amount ${amount}`);
});
This code listens for 'Transfer' events from a contract and logs details when the event occurs.
Execution Table
StepActionEvaluationResult
1Connect to blockchain providerProvider connectedProvider object ready
2Create contract instance with ABI and addressContract instance createdContract object ready
3Set event listener for 'Transfer'Listener registeredWaiting for events
4Event 'Transfer' emitted on blockchainEvent detected by listenerCallback triggered
5Callback logs event dataConsole logs transfer detailsUI or console updated
6No more eventsListener remains activeWaiting for next event
💡 Listener runs continuously; stops only if explicitly removed or page closed.
Variable Tracker
VariableStartAfter Step 1After Step 2After Step 3After Step 4Final
providerundefinedConnected provider objectConnected provider objectConnected provider objectConnected provider objectConnected provider object
contractundefinedundefinedContract instanceContract instanceContract instanceContract instance
listenerundefinedundefinedundefinedListener registeredListener activeListener active
eventDataundefinedundefinedundefinedundefinedEvent data receivedEvent data updated
Key Moments - 3 Insights
Why does the event listener keep running even after receiving one event?
Because the listener is registered to continuously watch for events (see execution_table step 6), it stays active until explicitly removed or the page is closed.
What happens if the blockchain provider is not connected before creating the contract?
Without a connected provider (execution_table step 1), the contract instance cannot interact with the blockchain, so event listening will fail or throw errors.
Why do we need the contract ABI and address to listen to events?
The ABI defines the event structure and the address points to the deployed contract; both are needed to decode and listen to events properly (execution_table step 2).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, at which step is the event listener registered?
AStep 2
BStep 3
CStep 4
DStep 5
💡 Hint
Check the 'Action' column for 'Set event listener' in execution_table.
According to variable_tracker, what is the state of 'eventData' after step 4?
AEvent data received
BListener registered
Cundefined
DContract instance
💡 Hint
Look at the 'eventData' row under 'After Step 4' in variable_tracker.
If the provider is not connected, what will happen when creating the contract instance?
AContract instance will be created successfully
BEvent listener will register anyway
CContract instance creation will fail or be undefined
DEvent data will be received immediately
💡 Hint
Refer to key_moments about provider connection and execution_table step 1.
Concept Snapshot
Listening to events on frontend:
1. Connect to blockchain provider.
2. Create contract instance with ABI and address.
3. Register event listener on contract.
4. When event fires, callback runs.
5. Update UI or log event data.
Listener stays active until removed or page closes.
Full Transcript
This visual trace shows how a frontend listens to blockchain contract events. First, the frontend connects to a blockchain provider. Then it creates a contract instance using the contract's ABI and address. Next, it sets up an event listener for a specific event, such as 'Transfer'. When the blockchain emits this event, the listener detects it and runs a callback function. This callback can log the event data or update the user interface. The listener remains active, waiting for more events until it is removed or the page is closed. Variables like provider, contract, listener, and eventData change state as the program runs. Key points include the continuous nature of listeners and the need for a connected provider and correct contract info.

Practice

(1/5)
1. What is the main purpose of listening to blockchain events on the frontend?
easy
A. To compile smart contracts
B. To send transactions to the blockchain
C. To react instantly to changes happening on the blockchain
D. To mine new blocks

Solution

  1. Step 1: Understand what events represent

    Events are signals emitted by smart contracts when something important happens.
  2. Step 2: Connect event listening to frontend behavior

    Listening to these events lets the frontend update immediately without waiting for manual refresh.
  3. Final Answer:

    To react instantly to changes happening on the blockchain -> Option C
  4. Quick Check:

    Listening to events = instant frontend updates [OK]
Hint: Events notify frontend about blockchain changes instantly [OK]
Common Mistakes:
  • Confusing event listening with sending transactions
  • Thinking events compile contracts
  • Believing events mine blocks
2. Which of the following is the correct way to start listening to an event named Transfer using ethers.js?
easy
A. contract.subscribe('Transfer', (from, to, amount) => { console.log(from, to, amount); });
B. contract.listen('Transfer', (from, to, amount) => { console.log(from, to, amount); });
C. contract.addEventListener('Transfer', (from, to, amount) => { console.log(from, to, amount); });
D. contract.on('Transfer', (from, to, amount) => { console.log(from, to, amount); });

Solution

  1. Step 1: Recall ethers.js event listening syntax

    In ethers.js, the method to listen to events is on.
  2. Step 2: Match the correct method with parameters

    The correct syntax is contract.on(eventName, callback).
  3. Final Answer:

    contract.on('Transfer', (from, to, amount) => { console.log(from, to, amount); }); -> Option D
  4. Quick Check:

    ethers.js uses .on() for events [OK]
Hint: Use .on() method to listen to events in ethers.js [OK]
Common Mistakes:
  • Using .listen() which does not exist in ethers.js
  • Using .addEventListener() which is DOM method, not ethers.js
  • Using .subscribe() which is not ethers.js syntax
3. Given the following code snippet, what will be logged when the Deposit event is emitted with arguments user='0x123' and amount=100?
contract.on('Deposit', (user, amount) => {
  console.log(`User ${user} deposited ${amount} tokens`);
});
medium
A. User undefined deposited undefined tokens
B. User 0x123 deposited 100 tokens
C. User [object Object] deposited 100 tokens
D. SyntaxError: Unexpected token

Solution

  1. Step 1: Understand event callback parameters

    The callback receives event arguments in order: user and amount.
  2. Step 2: Check the console.log output format

    The template string inserts user and amount correctly into the message.
  3. Final Answer:

    User 0x123 deposited 100 tokens -> Option B
  4. Quick Check:

    Event args used correctly = correct message [OK]
Hint: Event callback parameters match emitted event arguments [OK]
Common Mistakes:
  • Assuming parameters are undefined if not destructured
  • Confusing objects with strings in output
  • Expecting syntax errors from correct code
4. Identify the error in this code snippet that listens to an event and suggest the fix:
contract.on('Approval', (owner, spender, value) => {
  console.log(owner, spender, value);
});

// Later in the code
contract.off('Approval');
medium
A. The off method requires the same callback function to remove the listener
B. The event name should be lowercase 'approval' instead of 'Approval'
C. The callback function must be async to listen to events
D. The off method does not exist in ethers.js

Solution

  1. Step 1: Understand how to remove event listeners in ethers.js

    To remove a listener, you must pass the exact callback function used when adding it.
  2. Step 2: Check the code's off usage

    The code calls contract.off('Approval') without the callback, so it won't remove the listener.
  3. Final Answer:

    The off method requires the same callback function to remove the listener -> Option A
  4. Quick Check:

    Remove listener = same callback needed [OK]
Hint: Pass same callback to .off() to remove listener [OK]
Common Mistakes:
  • Calling .off() without callback removes nothing
  • Changing event name case incorrectly
  • Thinking callback must be async
5. You want to listen to a MessageSent event on your frontend and update the UI only for messages sent by the current user. Which approach correctly filters events before updating the UI?
hard
A. Listen to all MessageSent events and inside the callback check if sender === currentUser before updating UI
B. Use contract.on('MessageSent', callback, { filter: sender === currentUser }) to filter events automatically
C. Filter events by modifying the contract ABI to include only currentUser events
D. Listen to events only once using contract.once and update UI

Solution

  1. Step 1: Understand event filtering on frontend

    ethers.js does not support filtering events by passing filter objects in on method directly.
  2. Step 2: Use callback logic to filter events

    Listen to all events, then check inside the callback if the sender matches the current user before updating UI.
  3. Final Answer:

    Listen to all MessageSent events and inside the callback check if sender === currentUser before updating UI -> Option A
  4. Quick Check:

    Filter inside callback = correct approach [OK]
Hint: Filter events inside callback, not in .on() parameters [OK]
Common Mistakes:
  • Trying to filter events via .on() parameters
  • Modifying ABI to filter events (not possible)
  • Using .once() which listens only once, not continuously