Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Property 'map' does not exist on type 'Subject<{}>'

Tags:

angular

rxjs

ngrx

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();
    }
}
like image 879
user947871 Avatar asked Sep 30 '16 14:09

user947871


3 Answers

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.

like image 114
John Siu Avatar answered Nov 14 '22 12:11

John Siu


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 [email protected]. 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.

like image 38
cartant Avatar answered Nov 14 '22 13:11

cartant


Try to import map:

import {map} from 'rxjs/operator/map';
like image 3
kemsky Avatar answered Nov 14 '22 12:11

kemsky