wonderful world
wonderful world

Reputation: 11599

Sending events to EventHub using '@azure/event-hubs' gives error

I'm using Angular 19 and typescript to send an event to the EventHub from the browser. The npm package that I use is @azure/event-hubs. I'm not using server side node.js.

import {EventHubProducerClient} from '@azure/event-hubs';

As soon as that application starts, I get the following error:

browser-external:util:9 Module "util" has been externalized for browser compatibility. Cannot access "util.inherits" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.

How can I fix this error? Should I be using a different typescript npm package?

enter image description here

Upvotes: 0

Views: 42

Answers (1)

Dasari Kamali
Dasari Kamali

Reputation: 3649

The @azure/event-hubs package can’t be used directly in an Angular frontend since it’s built for Node.js.

Instead, I have set up a JavaScript backend API to send events to Azure Event Hub, while the Angular app listens for those events via a WebSocket connection.

Backend :

eventHubSender.js :

const { EventHubProducerClient } = require('@azure/event-hubs');
require('dotenv').config();

const connectionString = process.env.EVENT_HUB_CONNECTION_STRING;
const eventHubName = process.env.EVENT_HUB_NAME;
const client = new EventHubProducerClient(connectionString, eventHubName);

async function sendEvent(message) {
    const batch = await client.createBatch();
    batch.tryAdd({ body: message });
    await client.sendBatch(batch);
    console.log('Event sent:', message);
}

module.exports = { sendEvent };

server.js :

const express = require('express');
const cors = require('cors'); 
const { sendEvent } = require('./eventHubSender');
const WebSocket = require('ws');
require('dotenv').config();

const app = express();
const port = 3000;
app.use(cors());
app.use(express.json());

const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', (ws) => {
    console.log('Client connected');
    ws.on('message', (message) => {
        console.log('Received:', message);
    });
    ws.send(JSON.stringify({ message: 'Connected to WebSocket' }));
});

app.post('/send-event', async (req, res) => {
    const { message } = req.body;
    await sendEvent(message);
    wss.clients.forEach(client => {
        if (client.readyState === WebSocket.OPEN) {
            client.send(JSON.stringify({ message }));
        }
    });

    res.send({ status: 'Event sent' });
});

app.listen(port, () => console.log(`Server running on http://localhost:${port}`));

Frontend :

event-listener.service.ts :

import { Injectable } from '@angular/core';
import { environment } from '../environments/environment';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class EventListenerService {
  private socket: WebSocket;

  constructor() {
    this.socket = new WebSocket(environment.webSocketUrl);
  }

  getMessages(): Observable<string> {
    return new Observable(observer => {
      this.socket.onmessage = (event) => observer.next(event.data);
      this.socket.onerror = (error) => observer.error(error);
      this.socket.onclose = () => observer.complete();
    });
  }

  sendMessage(message: string): void {
    this.socket.send(message);
  }
}

app.component.ts :

import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common'; 
import { FormsModule } from '@angular/forms'; 
import { EventListenerService } from './event-listener.service';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [CommonModule, FormsModule],
  template: `
    <h1>EventHub App</h1>
    <input [(ngModel)]="message" placeholder="Type your message"/>
    <button (click)="sendEvent()">Send Event</button>
    <ul>
      <li *ngFor="let msg of receivedMessages">{{ msg }}</li>
    </ul>
  `,
  styles: []
})
export class AppComponent implements OnInit {
  message = '';
  receivedMessages: string[] = [];
  constructor(private eventService: EventListenerService) {}
  ngOnInit(): void {
    this.eventService.getMessages().subscribe(msg => {
      const data = JSON.parse(msg);
      this.receivedMessages.push(data.message);
    });
  }

  sendEvent(): void {
    fetch('http://localhost:3000/send-event', {
      method: 'POST',
      body: JSON.stringify({ message: this.message }),
      headers: { 'Content-Type': 'application/json' }
    }).then(() => (this.message = ''));
  }
}

environment.ts :

export const environment = {
    production: false,
    webSocketUrl: 'ws://localhost:8080' 
  };

Output :

enter image description here

enter image description here

Azure Event Hub :

enter image description here

Upvotes: 0

Related Questions