New js DDP client (SimpleDDP)


#21

The above approach works fine, except for the callback of the call…
When I run the code below, the method is called (because the console log appears), but its callback is not:

chrome-extension/index.js

server.call('testMethod',function(error,result){
       $("#test").text(result);
})

meteor/imports/api/methods.js

Meteor.methods({
       'testMethod': function( ){
            console.log('Test');
            return 'Testing the function';
       }
});

What I know from other DDPs is that sometimes calls don’t return callbacks, but rather promises or something different. I also tried the code below, without success:

const testCall = server.call('testMethod')
testCall.done(function(result){
        $("#test").text(result);
});

How does simpleDDP support callbacks?


#22

call returns a promise, so

server.call('testMethod').then(function(result) {
  $("#test").text(result);
}

check DOCS


#23

@gregivy You’re on fire, man. I’m well impressed with this work.


#24

@gregivy Thanks, it worked!


#25

Thanks :smiley:, @babrahams

I think I have to hold over a bit publishing version 1.2.0 because right now I am deeply testing it with different mobile web views and have some problems with scenarios like the lose of the internet connection and reconnection some time after etc.


#26

Hello!

News

  1. I found some really disturbing bug!
    If you connect to meteor server, subscribe for some publication, disconnect for long enough (>10s), make some changes in the publishing data and then reconnect again - simpleDDP local collection will be messed up. Instead of updating changed documents to the latest state, simpleDDP will make a duplicate with the same id inside its local collection. This happens because the newly created subscription does not know anything about it previous state and will send added ddp messages.
    This behavior is fixed in 1.2.0.
    However there are some questions left with removed ddp sync in the same scenario.
  1. I decided to push my 1.2.x branch on github, so you can check it out, but there is no documentation yet.
    https://github.com/Gregivy/simpleddp/tree/1.2.x
  2. I have replaced ddp.js with simpleddp-core. It is the same old ddp.js but with PRs included and few bugs excluded :slight_smile:
  3. Right now I am making tests, fixing some errors, improving API and reading Meteor repo about DDP. There are a lof of things I need to consider in 1.2.0.
  4. I am planning to make a good guide and push it to github pages, so if someone is willing to help and knows good constuctor or something like this you’re welcome :wink:

#27

Thanks for the heads up! I’m looking for a way to make this pluggable since React, Vue and Angular all have slightly different ways of connecting their Reactivity system. Any thoughts on it? right now I’m actually considering mapping onChange, etc to the Vue Store and create a local DB’ish storage there.


#28

I am successfully using in my Ionic v3 application (so in other words it is Angular 4 app) this approach (P.S. This is current 1.2.0 API):

// somewhere in the constructor
this.userId = localStorage.getItem('userid');

this.server = new simpleDDP({
      endpoint: 'ws://someserver.com/websocket',
      SocketConstructor: WebSocket,
      reconnectInterval: 1000
});

this.server.sub('usersub');
this.userCursor = server.collection('users')
                  .filter(user=>user.id==this.userId)
                  .reactiveOne({preserve:true});
this.user = this.userCursor.data;
<!--some class template -->
<div *ngIf="user.id && user.badges?.length > 0">
  <h1>My Badges</h1>
  <div *ngFor="let badge of user.badges">
    <img [src]="badge.picurl">
    <span>{{badge.title}}</span>
  </div>
</div>

This means that this.user is a reactive data source, when there is no data it is an empty object, when some changes happen it is being mutated to the right state. The key word is mutated, so the object remains the same until you remove this.userCursor.

The code reactiveOne({preserve:true}) means that we want a reactive data source as a first object passing previous conditions (filter in my example), and {preserve:true} means that if object is being removed by the subscription it stays untouched in simpleDDP collection storage.

If we use reactiveOne() or reactiveOne({preserve:false}) then there will be empty object {} in case of publication removes it. But it will be the same object, not some new {}.

If you need more complex behavior you can use onChange:

this.userObserver = this.userCursor.onChange({prev,next,fields}=>{
   // prev is previous state of the object or false if none
   // next is new state of the object or false if none
   // fields is an associative array of changed fields inside the document 
   // (value 1 means property was changed, 0 means removed)
  if ( prev && next && prev.score > next.score) {
     alert('You lost some points!');
  }
});

You can read more about onChange here.

And there is also reactive() for reactive collection or filtered/sorted collection.


#29

Hello!

SimpleDDP 1.2.0 is 75% ready!

You can watch project status by opening the link below.


#30

Nice work, I have two questions:

  • Is it possible to make a Meteor.call()? Don’t find it
  • Implement collection cache import/export. => like Minimongo? Will it be possible to save a Collection in AsyncStorage//localStorage?

Keep it up


#31

Thanks!

Of course, you can call methods.

let server = new simpleDDP(...);
...
server.call('somemethod',[arguments]); //returns promise, so use then or await

About the second question. I have already implemented import/export, so yeah from version 1.2.0 you can save all collection or any particular in any storage and load it when you need.

1.2.0 is almost done, I need to finish testing and documentation, but unfortunately good guide will take more time.


#32

Why would you use this over Meteor’s built in DDP?


#33

Its nice to connect non meteor applications with it or when Meteor is not an option and you require a socket based or realtime connection