5

So, I've seen multiple other posts about similar problems, but none of the solutions have helped.

I am also doing this development in IntelliJ IDEA 15, not Visual Studio. I am currently on Typescript 2.0.3.

import { Injectable } from '@angular/core';
import { Effect, StateUpdates, toPayload } from '@ngrx/effects';
import { Subject } from 'rxjs/Subject';
import 'rxjs/add/operator/mergeMap';
import 'rxjs/add/observable/dom/webSocket'
import 'rxjs/add/operator/map';

import { AppState } from '../reducers';
import { NGRXWebSocketService } from '../shared/ngrxWebsocket.service';
import { BASE_URL } from "../shared/ngrxWebsocket.service";

export interface WebsocketMessage {
    data: string
}

@Injectable()
export class WebsocketEffects {

constructor(private updates$:StateUpdates<AppState>,
            private ngrxWebSocketService: NGRXWebSocketService) {
}

@Effect() _recieve$ = this.ngrxWebSocketService.getSubject()
    .map((websocketUpdate: WebsocketMessage) => {
        let message = JSON.parse(websocketUpdate.data);
        return{ type: message.action, payload: message.payload}
    });
}

Edit 1:

Here is this NGRXWebsocketService.

import {Injectable} from '@angular/core';
import {$WebSocket, WebSocketConfig} from 'angular2-websocket/angular2-websocket'

export const BASE_URL = 'ws://' + location.hostname + ':9000/socket';

@Injectable()
export class NGRXWebSocketService {
    private socket: $WebSocket;

    constructor() {
        this.socket = new $WebSocket(BASE_URL);
    }

    public sendRequest(request) {
        return this.socket.send(request);
    }

    public reconnect() {
        this.socket = new $WebSocket(BASE_URL);
    }

    public getSubject() {
        return this.socket.getDataStream();
    }
}
user947871
  • 339
  • 6
  • 17

8 Answers8

5

This look like a typing issue during manual compilation.

When compiling within IDE, the IDE may have internal typing configuration, which does not exist in your project settings.

  1. npm install typings -g

  2. Check your package.json dependencies.

    es6-shim

    If you have es6-shim in dependencies, create typings.json in your project directory:

    {
        "globalDependencies": {
            "es6-shim": "registry:dt/es6-shim",
            "node": "registry:dt/node"
        }
    }
    

    core-js

    If you have core-js in dependencies, create typings.json in your project directory:

    {
        "globalDependencies": {
            "core-js": "registry:dt/core-js",
            "node": "registry:dt/node"
        }
    }
    
  3. typings install

  4. Try manual compile.

John Siu
  • 5,056
  • 2
  • 26
  • 47
4

In the code in your question, you appear to be doing what's required: you've imported the Subject and you've imported/added the map operator. So it's a bit of a mystery why you are receiving the TypeScript error. However, your recent edit to the question does raise one possibility.

It's apparent that NGRXWebsocketService imports an NPM module: angular2-websocket/angular2-websocket. And that module has a dependency on rxjs@5.0.0-beta.12. Note that this is a dependency and not a peerDependency.

It's entirely possible that you have two separate rxjs modules in your node_modules hierarchy: one that's being used in your app (and, therefore in WebsocketEffects) and another that's being used in angular2-websocket/angular2-websocket. If that is the case, TypeScript will consider the type returned by getSubject to differ from the type that you have imported and to which you have added the map operator (despite their both being called Subject).

You can verify whether or not this is actually the case by adding some temporary code to your WebsocketEffects class:

temp() {
    let subject: Subject<any> = this.ngrxWebSocketService.getSubject();
}

If angular2-websocket/angular2-websocket is using a separate rxjs install, you should see an error something like this:

TS2322: Type 'Subject<any>' is not assignable to type 'Subject<any>'.

You can also run the following NPM command to list the rxjs installs that are under your node_modules directory:

npm list rxjs

This potential for multiple rxjs module installations is something that should be addressed by the angular2-websocket/angular2-websocket author. However, if you do have multiple installations, there is something you might be able to do about it (as the rxjs versions are identical). If you uninstall and re-install angular2-websocket/angular2-websocket, it should use the rxjs module that you are using in your app (instead of installing its own).

In fact, all of the dependencies in angular2-websocket/angular2-websocket should be peer dependencies and not dependencies. I would recommend your raising this as an issue.

cartant
  • 57,105
  • 17
  • 163
  • 197
3

Try to import map:

import {map} from 'rxjs/operator/map';
kemsky
  • 14,727
  • 3
  • 32
  • 51
2

Looking at the source code for angular2-websocket it looks like getDataStream() returns a subject that emits MessageEvent.

Try this:

@Effect() _receive$ = this.ngrxWebSocketService.getSubject()
  .map((messageEvent: MessageEvent) => {
      let message = JSON.parse(messageEvent.data);
      return { type: message['action'], payload: message['payload'] };
  });
Caleb
  • 2,268
  • 2
  • 14
  • 16
1

For RXJS v6 you have to use the pipe() with map().

 this.ngrxWebSocketService.getSubject().pipe(
    map((websocketUpdate: WebsocketMessage) => {
        let message = JSON.parse(websocketUpdate.data);
        return{ type: message.action, payload: message.payload}
    }) 
 );

Hope this fix will help.

Puneet Sharma
  • 305
  • 3
  • 14
0

import 'rxjs/Rx'; should fix all problems

Gabi
  • 131
  • 1
  • 4
0

i try:

import 'rxjs/add/operator/map'

from here: https://github.com/webmaxru/pwa-workshop-angular/issues/2 and worked fine :)

NFRiaCowboy
  • 153
  • 1
  • 9
0

https://medium.com/coding-snippets/rxjs-5-5-property-map-does-not-exist

This helped me with the current version of angular and rxjs. Basically you need to use pipe instead of map, and call the rxjs map function within the pipe

sfa
  • 61
  • 7