# Listening to Events Using fabric-network

The Hyperledger Fabric Node.js SDK provides a number of methods to register listeners for different types of events. In this section, we will take a closer look at the **fabric-network** module capabilities.

As mentioned in the previous section, there are three types of events: a chaincode, or a contract, a transaction, or a commit, and block events. A listener can be registered in the network for any type of event using the corresponding functions.

* [**Network.addBlockListener**](https://hyperledger.github.io/fabric-sdk-node/release-2.2/module-fabric-network.Network.html#addBlockListener__anchor)**(listener, \[, options])** creates a block listener.
* [**Contract.addContractListener**](https://hyperledger.github.io/fabric-sdk-node/release-2.2/module-fabric-network.Contract.html#addContractListener__anchor)**(listener, \[, options])** registers a chaincode listener.
* [**Network.addCommitListener**](https://hyperledger.github.io/fabric-sdk-node/release-2.2/module-fabric-network.Network.html#addCommitListener__anchor)**(listener, peers, transactionID)** adds a transaction listener.

As you can see, each registering function takes the **listener** parameter. This parameter defines an event handler that is called when an event is received. Different types of events provide different information to be processed by callback functions.

A chaincode listener is passed the [**ContractEvent**](https://hyperledger.github.io/fabric-sdk-node/release-2.2/module-fabric-network.ContractEvent.html) object containing a chaincode identifier, event name, and payload. A chaincode event itself can be emitted from a chaincode using the **setEvent** function from the **ChaincodeStub** interface.

**setEvent(name: string, payload: Uint8Array): void**

**setEvent** allows a chaincode to set an event that should be included as part of a transaction on the response to a proposal. The event will be available within the transaction in a committed block regardless of the validity of the transaction.

🚩It is not possible to set multiple events within one transaction. Only the latest event will be included.

Block events are different from contract events since you have less control of what exactly is being output. A block listener receives the [**BlockEvent**](https://hyperledger.github.io/fabric-sdk-node/release-2.2/module-fabric-network.BlockEvent.html) object containing a fully decoded block in the JSON format. The main components of the block are a block header, block data, and block metadata.

The block header contains a block number (starting at 0 from the genesis block), the current block hash (a hash of all transactions in the current block), and the previous block hash. Block data contains an ordered list of transactions. Block metadata contains the time when the block was written, a certificate, a public key, and a signature of a block writer. You can read more about the block structure in the [official Node.js SDK documentation](https://hyperledger.github.io/fabric-sdk-node/release-2.2/global.html#Block).

A transaction listener receives two objects: [**CommitError**](https://hyperledger.github.io/fabric-sdk-node/release-2.2/module-fabric-network.CommitError.html) and [**CommitEvent**](https://hyperledger.github.io/fabric-sdk-node/release-2.2/module-fabric-network.CommitEvent.html). The **CommitError** object provides information about peer communication errors if any occurred. The **CommitEvent** object is an extended version of [**TransactionEvent**](https://hyperledger.github.io/fabric-sdk-node/release-2.2/module-fabric-network.TransactionEvent.html) containing a transaction ID, a transaction status and its validity marker. Based on these parameters, we can check transaction validity and trace the block a transaction was committed to.

Listeners of all types accept [**ListenerOptions**](https://hyperledger.github.io/fabric-sdk-node/release-2.2/module-fabric-network.ListenerOptions.html). These options can be configured to process only a part of a chain, receive filtered events or events with private data, etc. We will not dwell on this topic in the current chapter.
