Skip to content

Instantly share code, notes, and snippets.

@faceyspacey
Created April 29, 2016 06:21
Show Gist options
  • Save faceyspacey/5c00a477c1e70d4a3bfe3d045994dcb3 to your computer and use it in GitHub Desktop.
Save faceyspacey/5c00a477c1e70d4a3bfe3d045994dcb3 to your computer and use it in GitHub Desktop.
meteor ddp client for react native with additional promises and possible fix for HMR
import DDPClient from 'ddp-client';
import hash from 'hash.js';
import _ from 'lodash';
import EJSON from 'ejson';
import config from './config';
import { AsyncStorage } from 'react-native';
const trimString = (str) => str.replace(/^\s+|\s+$/gm,'');
class DDP extends DDPClient {
callPromise(methodName, params) {
params = params || undefined;
if (params && !_.isArray(params)) {
console.warn('Params must be passed as an array to ddp.call');
}
return new Promise((resolve, reject) => {
this.call(methodName, params, (err, result) => {
// callback which returns the method call results
if (err) {
reject(err);
} else {
resolve(result);
}
}, () => {
// callback which fires when server has finished
}
);
});
}
connectPromise() {
return new Promise((resolve, reject) => {
this.connect((error, wasReconnect) => {
if(error) {
reject(error);
} else {
resolve(wasReconnect);
}
});
});
}
loginWithTokenPromise(token=null) {
if(token) {
return this._loginWithToken(token);
}
else {
return AsyncStorage.getItem('loginToken')
.then((token) => {
if(token) return loginWithToken(token);
else throw new Error('No Login Token Found');
});
}
}
_loginWithToken(token) {
return this.callPromise("login", [{resume: token}])
.then((res) => this._onAuthResponse(null, res))
.catch((error) => this._onAuthResponse(error));
}
signUpWithEmailPromise(email, password, params={}) {
params = {
email: trimString(email),
password: this._sha256(password),
...params,
};
return this.callPromise('createUser', [params])
.then((res) => this._onAuthResponse(null, res))
.catch((error) => this._onAuthResponse(error));
}
loginWithEmailPromise(email, password) {
let params = {
user: {
email: trimString(email)
},
password: this._sha256(password)
};
return this.callPromise('login', [params])
.then((res) => this._onAuthResponse(null, res))
.catch((error) => this._onAuthResponse(error));
}
changePasswordPromise(oldPassword, newPassword) {
return this.callPromise('changePassword', [oldPassword, newPassword])
.then((res) => {
if(!res.passwordChanged) throw new Error('Could not change your password');
return true;
})
.catch((error) => {
throw new Error('Could not change your password');
});
}
subscribePromise(pubName, params) {
params = params || undefined;
if (params && !_.isArray(params)) {
console.warn('Params must be passed as an array to ddp.subscribe');
}
return new Promise((resolve, reject) => {
this.subscribe(pubName, params, () => {
resolve(true);
});
});
};
signUpWithEmail(email, password, params={}, cb) {
params = {
email: trimString(email),
password: this._sha256(password),
...params,
};
return this.call('createUser', [params], (err, res) => {
this._onAuthResponse(err, res);
cb && cb(err, res)
});
}
signUpWithUsername(username, password, cb) {
let params = {
username: trimString(username),
password: this._sha256(password)
};
return this.call('createUser', [params], (err, res) => {
this._onAuthResponse(err, res);
cb && cb(err, res)
});
}
loginWithEmail(email, password, cb) {
let params = {
user: {
email: trimString(email)
},
password: this._sha256(password)
};
return this.call("login", [params], (err, res) => {
this._onAuthResponse(err, res);
cb && cb(err, res)
});
}
loginWithUsername(username, password, cb) {
let params = {
user: {
username: trimString(username)
},
password: this._sha256(password)
};
return this.call("login", [params], (err, res) => {
this._onAuthResponse(err, res);
cb && cb(err, res)
});
}
loginWithToken(token=null, cb) {
if(typeof token === 'function') {
cb = token;
token = null;
}
if (token) {
this.call("login", [{resume: token}], cb);
}
AsyncStorage.getItem('loginToken')
.then((token) => {
if (token) {
this.call("login", [{resume: token}], cb);
}
});
}
logout(cb) {
AsyncStorage.multiRemove(['userId', 'loginToken', 'loginTokenExpires']).
then((res) => {
this.call("logout", [], cb);
});
}
user() {
return AsyncStorage.getItem('userId')
.then((userId) => {
if (userId) {
this.collections = this.collections || {};
this.collections.users = this.collections.users || {};
return this.collections.users[userId];
} else {
return null;
}
});
}
/** INTERNALLY USED METHODS **/
_onAuthResponse(err, res) {
if (res) {
let { id, token, tokenExpires } = res;
AsyncStorage.setItem('userId', id.toString());
AsyncStorage.setItem('loginToken', token.toString());
AsyncStorage.setItem('loginTokenExpires', tokenExpires.toString());
return res; //res response for use by promises
} else {
AsyncStorage.multiRemove(['userId', 'loginToken', 'loginTokenExpires']);
throw err;
}
}
_sha256(password) {
return {
digest: hash.sha256().update(password).digest('hex'),
algorithm: "sha-256"
};
}
}
let ddpClient;
export default function() {
return ddpClient = ddpClient || new DDP(config.ddpConfig);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment