Skip to content
This repository has been archived by the owner on Jan 10, 2018. It is now read-only.

Type 'Observable<any>' is not assignable to type 'Observable<any>' #338

Closed
mikedatsko opened this issue Feb 9, 2017 · 10 comments
Closed

Comments

@mikedatsko
Copy link

mikedatsko commented Feb 9, 2017

Hello guys,

I have two weird red warnings at TypeScript compiling. They became after update to the latest versions of @ngrx/core and @ngrx/store:

"@ngrx/core": "^1.1.0",
"@ngrx/store": "^2.2.1",
[default] event.actions.ts:29:5 
    Type 'Observable<Event>' is not assignable to type 'Observable<Event>'.
  Property 'source' is protected but type 'Observable<T>' is not a class derived from 'Observable<T>'.
[default] http.service.ts:199:12 
    Type 'Observable<any>' is not assignable to type 'Observable<any>'.
  Property 'source' is protected but type 'Observable<T>' is not a class derived from 'Observable<T>'.

event.actions.ts:

import { Injectable, forwardRef, Inject } from '@angular/core'
import { Store, Action } from '@ngrx/store'
import { BehaviorSubject, Observable } from 'rxjs'
import { AppStore, Event } from '../../interfaces'
import { EVENT_TYPES, EVENT_ACTION_TYPES, EVENT_STATUSES } from './'

@Injectable()
export class EventActions {
  event$: Observable<Event>

  private actions$: BehaviorSubject<Action> = new BehaviorSubject({
    type: undefined,
    payload: undefined
  })

  constructor(
    private store: Store<AppStore>
  ) {
    this.event$ = this.store.select(state => state.event)
    this.actions$.subscribe(action => this.store.dispatch(action))
  }

  new(event: Event) {
    this.actions$.next({
      type: EVENT_ACTION_TYPES.NEW,
      payload: event
    })
  }

  getItems(status?) {
    status = status || EVENT_STATUSES.STARTED

    const event: Event = <Event>{
      type: EVENT_TYPES.GET_ITEMS,
      status,
      payload: {}
    }

    this.new(event)
  }
}

Can you help me with this please? Or point me where to start mining.

@wizardnet972
Copy link

What file do you mean? event.actions.ts or event-actions.ts ? maybe some file are old and the other is new?

@mikedatsko
Copy link
Author

sorry @wizardnet972 )) the file is event.actions.ts, I corrected the name in the description)
I didn't changed nothing in the code, I just updated the ngrx.

@wizardnet972
Copy link

wizardnet972 commented Feb 12, 2017

In line 29 there is nothing.

So try to do:
rm -rf node_modules/
npm cache clean
npm install

works?

@mikedatsko
Copy link
Author

mikedatsko commented Feb 13, 2017

Thank you @wizardnet972
I did it, several times, it didn't help.
This is the http.service.ts file:

'use strict'

import { Injectable } from '@angular/core'
import { Http, Headers, Request, Response, RequestMethod } from '@angular/http'
import { Observable, Observer } from 'rxjs'
import { Router } from '@angular/router'
const isJson = require('is-json')

import { Log, Level } from 'ng2-logger/ng2-logger'
const log = Log.create('XHRService')
log.color = 'crimson'
log.fixedWidth = 30

const HEADERS = new Headers({
  'Content-Type': 'application/x-www-form-urlencoded'
})

@Injectable()
export class HttpService {
  
  env: string
  host: string
  type: string
  api: string
  data: any
  callback: Function = undefined

  constructor(
    private http: Http,
    private router: Router
  ) {
    // log.d('constructor')
    this.host = window.location.host + ':8080'
  }

  get(api: string, data?: any): Observable<any> {
    log.d('get')

    data = data || {}

    const url = `http://${this.host}/${api}/`

    const search = this.getBody(data)

    let options = {
      url: url,
      body: '',
      search: search,
      method: RequestMethod.Get
    }

    this.api = api

    return this.execute(options)
  }

  post(api: string, data?: any) {
    log.d('post')

    data = data || {}

    const body = this.getBody(data)

    let options = {
      url: `http://${this.host}/${api}/`,
      body: body,
      method: RequestMethod.Post
    }

    this.api = api

    return this.execute(options)
  }

  put(api: string, data?: any) {
    log.d('put')

    data = data || {}

    const body = this.getBody(data)

    let options = {
      url: `http://${this.host}/${api}/`,
      body: body,
      method: RequestMethod.Put
    }

    this.api = api

    return this.execute(options)
  }

  delete(api: string, data?: any) {
    log.d('delete')

    data = data || {}

    const body = this.getBody(data)

    let options = {
      url: `http://${this.host}/${api}/`,
      body: body,
      method: RequestMethod.Delete
    }

    this.api = api

    return this.execute(options)
  }

  external(path, api?: boolean) {
    api = typeof api === 'undefined' ? false : api
    let url = ''

    if (api) {
      url = `http://${this.host}/${path}/`
    } else {
      url = path
    }

    window.location.href = url;
  }

  private getBody(data) {
    let body = ''

    if (_.isEmpty(data)) {
      return body
    }

    let bodyTmp = []

    for (let i in data) {
      if (!!data[i]) {
        let queryItem = i + '=' + data[i]
        bodyTmp.push(queryItem)
      }
    }

    if (bodyTmp.length) {
      body = bodyTmp.join('&')
    }

    return body
  }

  private extractData(response: Response): Observable<any> {
    log.d('extractData()', Object.assign({}, response))

    let responseParsed: any = Object.assign({}, response)
    responseParsed.data = this.parseData(responseParsed)

    if (responseParsed.status === 401) {
      this.router.navigateByUrl('/logout')
    }

    return responseParsed
  }

  private handleError(response: Response): Observable<any> {
    log.d('handleError()', Object.assign({}, response))

    let responseParsed: any = Object.assign({}, response)
    responseParsed.data = this.parseData(responseParsed)
    
    if (responseParsed.status === 0) {
      responseParsed.status = 400
      responseParsed.data = {error: 'connection error'}
    }

    if (responseParsed.status === 401) {
      this.router.navigateByUrl('/logout')
    }

    return Observable.create(observer => observer.next(responseParsed))
  }

  private parseData(response) {
    let data: any
    
    if (response.hasOwnProperty('_body')) {
      try {
        data = JSON.parse(response._body)
      } catch (error) {
        data = {
          error: response._body
        }
      }
    }
    return data
  }

  private execute(options: any): Observable<any> {
    options.headers = HEADERS
    options.withCredentials = true

    // log.i('execute()', options)

    return this.http
      .request(new Request(options))
      .map(response => {return this.extractData(response)})
      .catch(error => {return this.handleError(error)})
  }
}

@tomasklingen
Copy link

Are you using npm link or symlinks? I've had similar messages.

@mikedatsko
Copy link
Author

@tomasklingen nope.
I'm thinking to move from ngrx to simple RxJS or clear Redux.

@robwormald
Copy link
Contributor

This generally means you have two copies of Rx installed - typically one nested inside of another package:
/node_modules
/node_modules/rxjs
/node_modules/some-library
/node_modules/some-library/node_modules/rxjs

@kolisko
Copy link

kolisko commented Jul 24, 2017

It is exactly what you say @robwormald. Npm link creates symlink to some-library which contains node_modules/rxjs. Could you tell me how to do it right way?

@brechtbilliet
Copy link

Any updates on this?

@mikedatsko
Copy link
Author

@brechtbilliet nope.
I made changes to stabilize current ngrx implementation and I created a simple StateService for Angular 4, which is working through callstack (not event notification system), ping me if you'll need a code.
And I use clean Redux for React apps.

@robwormald @kolisko no links and/or symlinks.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants