bmavity / ges-client

A node.js client library for (Get) Event Store
Other
30 stars 9 forks source link

Simple append example fails #57

Open delaneyj opened 9 years ago

delaneyj commented 9 years ago
const uuid = require('node-uuid');
const EventStore = require('ges-client');

const connection = EventStore();

connection.on('connect', ()=> {
    const streamId = 'intro-stream';
    const appendData = {
        expectedVersion:EventStore.expectedVersion.noStream,
        events: [
            {
                eventType: 'Foo',
                eventId: uuid.v4(),
                data: {
                    name: `Hello World!`,
                    number: Math.random()
                },
                metadata: {
                    addedDate: new Date().toISOString()
                }
            }
        ]
    };

    connection.appendToStream(streamId, appendData, (err, results)=> {
        if (err) return console.error(`Ooops`, err);

        connection.readStreamEventsForward(streamId, {start: 0, count: 1}, (err, results)=> {
            if (err) return console.error(`Oppps read:`, err);

            console.log(results.Events);
        });
    });
});

This gives me an error of

node_modules\node-uuid\uuid.js:67
    s.toLowerCase().replace(/[0-9a-f]{2}/g, function(oct) {
     ^

TypeError: Cannot read property 'toLowerCase' of undefined

Looking through the code it appears you are using EventId, though the README.md doesn't discuss the internals of what events look like. Captializing EventType, EventId, Data and Metadata however gives me

protobufjs\node_modules\bytebuffer\dist\ByteBufferNB.js:378
                throw TypeError("Illegal buffer");
                ^

TypeError: Illegal buffer

What would be the correct version of the initial test code?

bmavity commented 9 years ago

Hi,

Sorry that the documentation is lacking. For now, the way to fix your code would be to create the event in one of the two following ways:

const uuid = require('node-uuid');
const EventStore = require('ges-client');

const data = new Buffer(JSON.stringify({
                    name: `Hello World!`,
                    number: Math.random()
                });
const metadata = new Buffer(JSON.stringify({
                    addedDate: new Date().toISOString()
                });

const event1 = EventStore.createEventData(uuid.v4(), 'Foo', true, data, metadata);

or

const event1 = {
                Type: 'Foo',
                EventId: uuid.v4(),
                Data: new Buffer(JSON.stringify({
                    name: `Hello World!`,
                    number: Math.random()
                })),
                Metadata: new Buffer(JSON.stringify({
                    addedDate: new Date().toISOString()
                }),
               // You likely want to add IsJson here
               IsJson: true
            }

There is something more user-friendly coming in the next release, which will allow javascript objects to be passed into the createEventData function (see https://github.com/bmavity/ges-client/blob/dev/eventData.js ), but the buffers are ultimately necessary for the EventStore.

Edit: Fixed issue with Type property

delaneyj commented 9 years ago

Thanks for the heads up, dealing with the buffers directly is fine, and long as I know that's what you need to do. Probably should keep open until the README.md matches this.

delaneyj commented 9 years ago

So the first way worked fine, the second however gives this error

ges-client\node_modules\protobufjs\dist\ProtoBuf.js:2640
                        throw(e);
                        ^

Error: Illegal value for Message.Field .EventStore.Client.Messages.WriteEvents.events: .EventStore.Client.Messages.NewEvent (Error: Missing at least one required field for Message .EventStore.Client.Messages.NewEvent: .EventStore.Client.Messages.NewEvent.eventType)
    at Error (native)

Its appears you need Type instead of EventType. Is this a bug or as designed? Also a simple es6 class seems to make this a little cleaner to work with...

class EventStoreEvent {
    constructor(type, data, metadata) {
        this.Type = type;
        this.EventId = uuid.v4();
        this.Data = new Buffer(JSON.stringify(data));
        this.Metadata = new Buffer(JSON.stringify(metadata));
        this.IsJson = true;
    }
}
const event3 = new EventStoreEvent(`Foo`, {
    name: `Hello World`,
    number: Math.random()
}, {
    addedDate: new Date().toISOString()
});

I tried using the es6 class version in the appendToStream events array and worked fine.

bmavity commented 9 years ago

I fixed the typo in the above, thanks for the heads up.

As far as ES6 goes, I will eventually move that way, but I need to do a bit more reading on the proper way for module to handle this when it is still targeting v0.10.x.