Urigo / Ionic2CLI-Meteor-WhatsApp

WhatsApp Clone tutorial with Ionic 2.0 CLI and Meteor Server
https://www.angular-meteor.com/tutorials/whatsapp2/ionic/setup
163 stars 185 forks source link

Property 'startWith' does not exist on type 'ObservableCursor<Message>'. #184

Open kenpachi-zaraki opened 6 years ago

kenpachi-zaraki commented 6 years ago

Whenever I launch "ionic serve", I get error below. I've just completed chapter 4 in the guide: https://angular-meteor.com/tutorials/whatsapp2/ionic/meteor-server-side

Here is the complete stacktrace. What am I doing wrong?

Starting app-scripts server: --address 0.0.0.0 --port 8100 --livereload-port 35729 --dev-logger-port 53703 --nobrowser - Ctrl+C to cancel [16:28:07] watch started ... [16:28:07] build dev started ... [16:28:07] clean started ... [16:28:07] clean finished in 1 ms [16:28:07] copy started ... [16:28:07] deeplinks started ... [16:28:07] deeplinks finished in 78 ms [16:28:07] transpile started ... [16:28:13] typescript: src/pages/chats/chats.ts, line: 18 Property 'mergeMap' does not exist on type 'ObservableCursor'.

  L17:  .find({})
  L18:  .mergeMap((chats: Chat[]) =>
  L19:      Observable.combineLatest(

[16:28:13] typescript: src/pages/chats/chats.ts, line: 23 Property 'startWith' does not exist on type 'ObservableCursor'.

  L22:  .find({chatId: chat._id})
  L23:  .startWith(null)
  L24:  .map(messages => {

[16:28:13] dev server running: http://localhost:8100/

[OK] Development server running! Local: http://localhost:8100 External: http://10.0.2.15:8100 DevApp: whatsapp@8100 on debian

kenpachi-zaraki commented 6 years ago

In the browser:

image

kenpachi-zaraki commented 6 years ago

In the following method, mergeMap is not found within ObservableCursor. Has it been removed ?

ngOnInit() { this.chats = Chats .find({}) .mergeMap((chats: Chat[]) => Observable.combineLatest( ...chats.map((chat: Chat) => Messages .find({chatId: chat._id}) .startWith(null) .map(messages => { if (messages) chat.lastMessage = messages[0]; return chat; }) ) ) ).zone(); }

kenpachi-zaraki commented 6 years ago

If I add the 2 lines below directly at the beginning of ngOnInit(), it will work: const Chats = new MongoObservable.Collection('chats'); const Messages = new MongoObservable.Collection('messages');

However if I use the imports: "Chats" and "Messages" from "api/server/collections", it won't work! Can you please explain why?

mikenetcode commented 6 years ago

Just tried to complete the tutorial too and just completed chapter 8. Actually I'm trying to migrate my own app from ionic 1 & angular 1 with meteor backend and I'm not into typescript so far. So I hope my explanations are correct.

If you install all packages now you actually use typescript 2.6, angular 5 and rxjs 5.5 and that seems to be the major problem.

First you need to pipe all operators and change the imports to lettabale operators, like mentioned here: https://medium.com/coding-snippets/rxjs-5-5-property-map-does-not-exist-on-type-observable-e825129c2068

Also you have to change the composite publication of chats on meteor side: Meteor.publishComposite('chats', function(): PublishCompositeConfig<Entity> { to Meteor['publishComposite']('chats', function(): PublishCompositeConfig<Entity> { like mentioned here: https://github.com/Urigo/angular-meteor/issues/1499

After this you still get errors like: Type 'Observable<Chat[]>' is not assignable to type 'Observable<Chat[]>'. This generally means you have two copies of RxJs installed, like mentioned here: https://github.com/Urigo/Ionic2CLI-Meteor-WhatsApp/issues/56, https://github.com/ngrx/store/issues/338, https://stackoverflow.com/questions/42917003/type-observableany-is-not-assignable-to-type-observableany

In our special case we do not really have 2 versions of RxJs installed, but typescript 2.4.2+ detects the symlink of the node_modules dir in the api dir (= meteor server) as a second version. To fix this just completely seperate client & server:

  1. remove all symlinks from api dir and copy orginal files (2. run the meteor-client bundler again (npm run meteor-client:bundle) and copy meteor-client.js to ionic's node_modules dir)
  2. copy collections dir and models.ts (from api/server) to ionic's src dir
  3. correct paths of all collections and model imports
  4. remove api alias from webpack.config & tsconfig.json
  5. move api dir out of ionic project dir
  6. start meteor & ionic manually

Things should work out again ;-)

mikenetcode commented 6 years ago

@poparotsy I got the same error a few days ago when i deleted the node_modules dir in the ionic project and reinstalled all npm packages (with npm install). This means one or more new package versions create this error. I guess it is a typescript version, which is 2.7+. I use typescript 2.6.2. i attached my package-lock.json file. Maybe it helps you. Actually i also get some errors when i create the meteor-client.js again with meteor-client-bundler. Didn't find out why these errors occour by now. package-lock.json.txt

poparotsy commented 6 years ago

@mikenetcode, regenerating node_modules didn't help, and typescript was 2.6 already!. also, cloning && running Ionic2CLI-Meteor-WhatsApp itself which on angular 4.4, still complains about .zone() doesn't exist on type Observable<{}>, among other errors,

`[01:15:18] typescript: src/pages/messages/messages.ts, line: 67 Argument of type 'Observable' is not assignable to parameter of type 'Observable'. Property 'source' is protected but type 'Observable' is not a class derived from 'Observable'.

  L66:  // Remove the scroll listener once all messages have been fetched
  L67:  .takeUntil(this.autoRemoveScrollListener(messagesCount))
  L68:  // Filter event handling unless we're at the top of the page

[01:15:18] typescript: src/pages/messages/messages.ts, line: 214 Property 'zone' does not exist on type 'Observable<{}>'.

 L213:    this.message
 L214:  ).zone().subscribe(() => {
 L215:    // Zero the input field

[01:15:18] typescript: src/pages/messages/messages.ts, line: 224 Property 'zone' does not exist on type 'Observable<{}>'.

 L223:    `${location.lat},${location.lng},${location.zoom}`
 L224:  ).zone().subscribe(() => {
 L225:    // Zero the input field

[01:15:18] typescript: src/pages/messages/messages.ts, line: 258 Property 'zone' does not exist on type 'Observable<{}>'.

 L257:      picture.url
 L258:    ).zone().subscribe();
 L259:  });

[01:15:18] typescript: src/services/phone.ts, line: 54 The 'this' context of type 'Observable' is not assignable to method's 'this' of type 'Observable'. Property 'source' is protected but type 'Observable' is not a class derived from 'Observable'.

  L53:  try {
  L54:    var msg = await startObs.takeUntil(timeoutObs).toPromise();
  L55:  } catch (e) {

`

mikenetcode commented 6 years ago

@poparotsy When you clone the original project just look at the package.json in detail. Not all versions are fixed, like angular and rxjs. In case of typescript ("typescript": "^2.4.2") always the latest version of major release 2 is installed. Actually this would be 2.8.3 (npm show typescript version). Just check the versions directly in node_modules dir (e.g.: node_modules/typescript/package.json). Did you completely seperate meteor server (api dir) and the ionic project?

poparotsy commented 6 years ago

@mikenetcode , Ionic2CLI-Meteor-WhatsApp, typescript was 2.4.2 && angular 4.4.3,

The problem was with the latest meteor-rxjs v 0.4.11, So, installing meteor-rxjs@0.4.10 corrected the zone() not a function error.

mikenetcode commented 6 years ago

@poparotsy Good to know. Thanks for the info.