New js DDP client (SimpleDDP)

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?

call returns a promise, so

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

check DOCS

2 Likes

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

2 Likes

@gregivy Thanks, it worked!

1 Like

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.

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:
1 Like

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.

1 Like

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.

Hello!

SimpleDDP 1.2.0 is 75% ready!

You can watch project status by opening the link below.

2 Likes

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

1 Like

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.

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

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

3 Likes

Happy new year!

simpleDDP 1.2.0 is out!

It’s a grand update since 1.1.10, this two versions are incompatible so check out the readme. I have not done tutorial yet, but I hope to finish it in January.

The new version has reactive collections, objects, reducers, import/export and a lot more (only API description is ready for now)! The most important part in my opinion is stability and tests. This version has passed a lot of real tests in my company and I have checked it to work as Meteor original DDP package.

In a few days I will update login plugin!

Good luck and Happy New Year!

5 Likes

Going to play with it. Might create an integration with nuxt :thinking: happy new year! :yum:

3 Likes

Hi everyone!

I have updated login plugin (2.0.0):

  • Added new behaviour: now this plugin does login attempt and only after allows simpleddp to send other methods call and resubscriptions on reconnection.
  • Added new event ‘onResumeFailed’.

So you don’t have to worry about re-auth and right order of ddp messages on reconnections.
To achieve this I have also updated simpleddp-core package and simpleddp itself to 1.2.1.

I think now you can use simpleddp in your real projects and it has everything you need for easy integration with react or angular or vue.

Now the roadmap is:

  • Full tutorial ( a web-site)
  • Native plugins for react, angular and vue.
  • More plugins, especially for mobile developers, like integrations with local dbs.

The first step is not easy as it may seems, there are not just one but few different approaches in reactivity in new simpleddp and all of them are needed to be explained (custom, one which is better for angular/vue and one which is better for react).

I am thinking about posting different use cases (examples) here few times a week and with your help create a tutorial/documentation (fix bugs / improve …). What do you think guys?

5 Likes

@gregivy It’s great work! Your library may help me create frontend clients by using any frontend libraries and no depend from meteor. Thanks!

At this moment I have meteor app and I’m going to try split on two - frontend client and server. This app using accounts-password package and I don’t understand how to use methods of this package (loginWithPassword for example). If it’s not possible now how did you make authorization for your apps?

2 Likes

Thank you @kerf!

It is possible to use loginWithPassword or use any other (also your custom auth) based on Meteor Accounts. Here is the plugin https://github.com/Gregivy/simpleddp-plugin-login.
Example for Accounts.Password included in readme.

simpleDDP is made with understanding of how Meteor Accounts authorization works. So you don’t have to think about the re-auth on reconnections, about the order of methods calls on reconnection (authorization always comes first), about resubscribing after authorization, tokens, etc.

1 Like

Cool! I’ll try this one.

Thanks a lot again!

@gregivy one more question:

When we use standart meteor app if we logged in once then after reload page user login automatically. As far as I understand it because login token saved in localStorage.

And if we use simpleddp-plugin-login then we should save token after login manually. And we should use login function something like that: server.login({resume: 'stored token here'}) for autologin?