angulartypescriptsignalr

starting a signalr stream to serverside iterates over array functions


I build a SPA with angular and hit the problem for message size in signalR, but before increasing and just moving the problem to later, I wanted to split the message with a stream.

it is pretty straight forward:

        const subject = new Subject<any>();

        try
        {
            await this.hubConn.send("Values", id, subject) // X
                .catch(err => console.error(err));

            for (let i = 0; i < values.length; ++i)
                subject.next(values[i]);

            subject.complete();
        }
        catch (err: any)
        {
            subject.error('Error');
            console.error(err.message);
        }

But I get an error in the line marked with // X error message signalR

after some investigation I found that on the second iteration the streamId is distinct: debugging streamId

I build a small example to check what happens:

var streams = [];
streams[4] = {};

for (const streamId in streams)
    console.debug(streamId);

which gives me this result:

4
distinct
equals
firstOrDefault
lastOrDefault
pushSorted

but that means that iterating over the keys always iterates over the array functions, but I found nothing regarding this problem...

I'm using:

angular 16.2
typescript 5.1.6
signalR 7.0.9 and 8.0.7 (tried both)
nodejs 16.20.2
and I have the target ES2022

so either no one ever tried streaming (which sounds way to unlikely), I have a version incompatibility or I have some mistake in my code which I can't see...

Does anyone has an idea why this might not work?

// Edit: Here the serverside method to receive the values:

[HubMethodName(nameof(Values))]
public async Task Values(string id, IAsyncEnumerable<object> values)
{
    try
    {
        object[] result = null;
        if (values != null)
            result = await values.ToArrayAsync();

        Debug.WriteLine(result);
    }
    catch (Exception ex)
    {
        SystemLogger.LogCritical("{ex}", ex);
    }
}

Solution

  • It's very likely that you are using a library that modifies Array.prototype in a wrong way:

    Array.prototype.distinct = function() { return [...new Set(this)]; };
    

    The correct way is to use Object.defineProperty (or even better, not to change the core prototypes at all). In this case the property would not become enumerable.

    Object.defineProperty(Array.prototype, 'distinct', {
        value: function() { return [...new Set(this)]; }
    });