How to use bluebird Promise.map concurrency control without getting meteor.bindenvironment errors


#1

Hi,

I would like to use this bluebird code:

How can I use bluebird in meteor, without need to do extra stuff like solving the bind environment errors?

Complete code here

import { Meteor } from 'meteor/meteor';
import { http } from 'meteor/meteor';
import { Apps, TemplateApps } from '/imports/api/apps.js';
import { Streams } from '/imports/api/streams.js';
import { config } from '/imports/api/config.js'; 
import { engineConfig } from '/imports/api/config.js'; 
import { certs } from '/imports/api/config.js'; 
var fs = require('fs');
var qsocks = require('qsocks');
var QRS = require('qrs');
import { Promise } from 'meteor/promise';
var qrs = null;
var generatedAppGuid = '';




function getApps(){
	console.log('server: getApps');
	return qsocks.Connect(engineConfig).then(function(global) {

  //We can now interact with the global class, for example fetch the document list.
  //qsocks mimics the Engine API, refer to the Engine API documentation for available methods.
  global.getDocList().then(function(docList) {

  	// docList.forEach(function(doc) {
  	// 	console.log(doc.qDocName);
  	// });
  	return docList;
  });

});
	
};

function generateStreamAndApp (customers) {
	console.log('METHOD called: generateStreamAndApp for the template apps as stored in the database of the fictive OEM');
	// check(customers, Array);
	//for each customer
	//create stream if not already exist
	//copy app
	//publish to stream
	//add 'generated' tag
	var templateApps = TemplateApps.find().fetch();
	if(!TemplateApps.find().count()){//user has not specified a template
		throw new Meteor.Error('No Template', 'user has not specified a template for which apps can be generated');
	} 
	if(!customers.length){ // = 0
		throw new Meteor.Error('No customers', 'user has not specified at least one customer for which an app can be generated');
	} 
	// console.log('customers are', customers);
	// console.log('template apps are',templateApps);
	// console.log('2: the templateAppGuid are',templateAppsGuids);

//FOR EACH TEPMPLATE
	var generationPromise =  Promise.all(_.map(templateApps, function(templateApp){
		console.log('the current template app: ', templateApp.name);
		return Promise.all(_.map(customers, function(customer){	

//FOR EACH CUSTOMER
			console.log('############## START CREATING THE TEMPLATE '+templateApp.name+' FOR THIS CUSTOMER: '+customer.name);

			var stream = Streams.findOne({name:customer.name});  //Find the stream for the name of the customer in Mongo, and get his Id from the returned object
			if(stream){
				var streamId = stream.id;
			}
			// console.log('!!! The stream Id found is: ',streamId);			
			var myPromise = new Promise(function(resolve, reject) {
				if(!streamId){ 
					console.log('No stream for customer exist, so create one: '+customer.name);
					createStream( customer.name)
					.then(
						function fulfilled (result) {
							// console.log('stream create promosi fulfilled, result of create stream promise', result);
							streamId = result.id;
							resolve('created stream with id '+result.id);
						},
						function Rejected (error){
							// console.error('Promise Rejected: Error when trying to copy the app', error);
							reject('Promise Rejected: Error when trying to create a stream');
						})
				} else{
					// console.log('No need to create a stream, because it already exists: '+Streams.findOne({name:customer.name}).count()+' time(s)');
					resolve('No need to createa a stream, already exists'+Streams.find({name:customer.name}).count()+' time(s)');
				} 
			})
			.then(function(resultOfStreamStep){ //Copy the APP
				console.log('2 COPY the app: result Of create Stream Step: ', resultOfStreamStep);
				return copyApp(templateApp.guid, customer.name+' - ' + templateApp.name)
			})
			.then(function(appGuid){ //Publish into streamId
				console.log('3 PUBLISH: APP HAS BEEN COPIED AND HAS RECEIVED GUID', appGuid);
				return publishApp(appGuid, templateApp.name, streamId) //return publishApp(appGuid, templateApp.name+' - ' +customer.name , streamId)
			})
			.then(function(){
				console.log('############## FINISHED CREATING THE TEMPLATE '+templateApp.name+' FOR THIS CUSTOMER: '+customer.name);
				console.log('	');
			})		
			.catch(function(err) {
				console.error(err);
				// throw new Meteor.Error('Catch error app generation chain: App generation failed', 'err');
			}).done();	
			return myPromise;

		})) //each template Promise.all
	}) //each customer
	) //promise all generation total
};


function copyApp (guid, name) {
	console.log('Copy template: '+guid+' to new app: '+name);
	check(guid, String);
	check(name, String);

	return new Promise(function(resolve, reject){ 
		HTTP.call( 'post', 'http://'+config.host+'/'+config.virtualProxy+'/qrs/app/'+guid+'/copy?name='+name+'&xrfkey='+config.xrfkey, 
		{
			headers: {
				'hdr-usr' : config.headerValue,
				'X-Qlik-xrfkey': config.xrfkey
			}
		}, function( error, response ) {
			if ( error ) {
				console.error('error app copy',  error );
				throw new Meteor.Error('error app copy', error)
				reject(error);
			} else if (response){
				// console.log('Copy app:  HTTP request gave response', response.data );
				console.log('Copy app:  the generated guid: ', response.data.id);				
				resolve(response.data.id); //return app Guid
			}
		});
	})
};

function publishApp (appGuid, appName, streamId) {
	console.log('Publish app: '+appGuid+' to stream: '+streamId);
	check(appGuid, String);
	check(appName, String);
	check(streamId, String);

	return new Promise(function(resolve, reject){ 
		HTTP.call( 'put', 'http://'+config.host+'/'+config.virtualProxy+'/qrs/app/'+appGuid+'/publish?name='+appName+'&stream='+streamId+'&xrfkey='+config.xrfkey, 
		{
			headers: {
				'hdr-usr' : config.headerValue,
				'X-Qlik-xrfkey': config.xrfkey
			}
		}, function( error, response ) {
			if ( error ) {
				console.error('error publishApp',  error );
				throw new Meteor.Error('error publish App', error)
				reject(error);
			} else {
				// console.log( response );
				resolve('publishApp success');
			}
		});
	})
	
};


function deleteApp (guid) {
	return HTTP.call( 'DELETE', 'http://'+config.host+'/'+config.virtualProxy+'/qrs/app/'+guid+'?xrfkey='+config.xrfkey, 
	{
		headers: {
			'hdr-usr' : config.headerValue,
			'X-Qlik-xrfkey': config.xrfkey
		}
	}, function( error, response ) {
		if ( error ) {
			console.error( error );
			throw new Meteor.Error('error app delete', error)
		} else {
			console.log( response );
			return response;
		}
	});
};

function deleteStream (guid) {
	return HTTP.call( 'DELETE', 'http://'+config.host+'/'+config.virtualProxy+'/qrs/stream/'+guid+'?xrfkey='+config.xrfkey, 
	{
		headers: {
			'hdr-usr' : config.headerValue,
			'X-Qlik-xrfkey': config.xrfkey
		}
	}, function( error, response ) {
		if ( error ) {
			console.error( error );
			throw new Meteor.Error('error stream delete', error)
		} else {
			console.log( response );
			return response;
		}
	});
};

function createStream (name) {
	console.log('create the stream with name', name);
	var myPromise = qrs.post('/qrs/stream', null,  {"name": name})
	.catch(err => {
		console.log(err);
		throw new Meteor.Error(err)
	})
	return myPromise
};

function getStreams () {
	return qrs.get('/qrs/stream/full');
};

Meteor.methods({  
	generateStreamAndApp (customers) {
		check(customers, Array);
		generateStreamAndApp(customers)
		.then(
			function fulfilled (result) {
				console.log('generation promise fulfilled, result of promise', result);
				// resolve('Generation success ');
				return 'Generation success';
			},
			function Rejected (error){
				console.error('Promise Rejected: Error when trying generate the apps', error);
				throw new Meteor.Error('Generation failed','Promise Rejected: Error when trying to generate the apps');
			})
	},
	getApps () {
		return new Promise((resolve, reject) => {
			qsocks.Connect(engineConfig)
			.then(function(global) {
				global.getDocList().then(function(docList) {
					resolve(docList) ;
				});
			})
		})
		.catch(err => {
			throw new Meteor.Error(err)
		})
	},
	copyApp (guid, name) {
		check(guid, String);
		check(name, String);
		return copyApp(guid,name);
	},
	deleteApp (guid) {
		check(guid, String);
		return deleteApp(guid);
	},
	deleteStream (guid) {
		check(guid, String);
		return deleteStream(guid);
	},
	countApps(){
		return qrs.get('/qrs/app/count');
	},
	countStreams(){
		return qrs.get('/qrs/stream/count');
	},
	createStream (name) {
		return createStream(name);
	},
	getStreams () {
		return getStreams();
	},
	getSecurityRules () {
		return getSecurityRules();
	},
	// updateAppsCollection(){
	// 	console.log('Method: update the local mongoDB with fresh data from Qlik Sense');

	// 	try{
	// 		Apps.remove();
	// 	}
	// 	catch(error){console.log(err)};

	// 	var myPromise = qrs.get( '/qrs/app/full');

	// 	myPromise.then(
	// 		function(docList){					
	// 			try{
	// 				console.log('try to insert document array into mongo', docList);
	// 				Apps.insert(docList, 
	// 					function(err,res){
	// 						console.log("insert error: ",err); 
	// 						console.log("insert result: ",res);
	// 					}
	// 					);
	// 				console.log('inserted document ', docList);	
	// 			}
	// 			catch(error){console.log(err)}

	// 		}, function (error) {
 //   				 console.error('uh oh: ', error);   // 'uh oh: something bad happened’
 //   				});

	// 	myPromise.catch(function(error) {
	// 		console.log('Caught!', error);
	// 	});

	// }
});

Meteor.startup(() => {  	
	
	qrs = new QRS(config);

	// console.log('Meteor server has started. Calling updateAppsCollection');
	// Meteor.call('updateAppsCollection');


});




//CODE WITH NPM QRS, THAT GENERATES DOUBLE APPS
// function copyApp (guid, name) {
// 	console.log('Copy template: '+guid+' to new app: '+name);
// 	check(guid, String);
// 	check(name, String);
// 	return qrs.post('/qrs/app/'+guid+'/copy', [{"key": "name", "value": name}])
// 	.then(
// 		function fulfilled (result) {
// 			console.log('result of copy app promise', result);
// 			return result;
// 		},
// 		function Rejected (error){
// 			console.error('Promise Rejected: Error when trying to copy the app', error);
// 			throw new Meteor.Error('App copy failed', 'App copy failed');
// 		})
// };


// return 
	// qsocks.Connect(engineConfig)
	// .then(function(global) {
	// 	console.log(global);
	// 	return global.getDocList()
	// }).then(function(docList){
	// 	console.log('DE DOC LIST IS: ', docList);
	// 	return docList;
	// })

Thank you!


#2

Any help would be appreciated.

Somehow I am struggling with promises in meteor. I tried adding and removing the meteor:promise package and now I tried to use the bluebird package, but I always get this error.

Question:

  • how do I import the bluebird package (preferred because I need map() with sync control) or the normal meteor promises package. It is unclear for me what I do have to import and what is standard available.
Method: update the local mongoDB with fresh data from Qlik Sense
I20160531-20:57:45.356(2)? try to insert document array into mongo
I20160531-20:57:45.357(2)? [Error: Meteor code must always run within a Fiber. Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment.]
import { Meteor } from 'meteor/meteor';
import { http } from 'meteor/meteor';
import { Apps, TemplateApps } from '/imports/api/apps.js';
import { Streams } from '/imports/api/streams.js';
import { config } from '/imports/api/config.js'; 
import { engineConfig } from '/imports/api/config.js'; 
import { certs } from '/imports/api/config.js'; 
import {Customers} from '/imports/api/customers.js'; ;

var fs = require('fs');
var qsocks = require('qsocks');
var QRS = require('qrs');
// import { Promise } from 'meteor/promise';
import { P } from 'meteor/mvrx:bluebird';

....

//my method...
	updateAppsCollection() {
		console.log('Method: update the local mongoDB with fresh data from Qlik Sense');

		try {
			Apps.remove();
		}
		catch (error) { throw new Meteor.Error('Unable to remove apps from collection',error.message) };

		var myPromise = qrs.get('/qrs/app/full')
		.then(
			function fulfilled (docList) {
				try {
					console.log('try to insert document array into mongo');
					docList.forEach(doc => {
						Apps.insert(doc);
						console.log('inserted document ', doc.qDocName);
					});
				}
				catch (error) { console.log(error) }

			}, function Rejected (error) {
				console.error('uh oh: ', error);   // 'uh oh: something bad happened’
			}).catch(function(error) {
				console.log('Caught!', error);
				throw new Meteor.Error('Unable to get streams from Sense', error.message);
			});
		}//end update apps
	});

Meteor.startup(() => {
	qrs = new QRS(config);
});




//CODE WITH NPM QRS, THAT GENERATES DOUBLE APPS
// function copyApp (guid, name) {
// 	console.log('Copy template: '+guid+' to new app: '+name);
// 	check(guid, String);
// 	check(name, String);
// 	return qrs.post('/qrs/app/'+guid+'/copy', [{"key": "name", "value": name}])
// 	.then(
// 		function fulfilled (result) {
// 			console.log('result of copy app promise', result);
// 			return result;
// 		},
// 		function Rejected (error){
// 			console.error('P Rejected: Error when trying to copy the app', error);
// 			throw new Meteor.Error('App copy failed', 'App copy failed');
// 		})
// };


// return 
	// qsocks.Connect(engineConfig)
	// .then(function(global) {
	// 	console.log(global);
	// 	return global.getDocList()
	// }).then(function(docList){
	// 	console.log('DE DOC LIST IS: ', docList);
	// 	return docList;
	// })

my packagelist


C:\Meteor projects\qrsmeteor>meteor list
aslagle:reactive-table      0.8.31  A reactive table designed for Meteor
autopublish                 1.0.7  (For prototyping only) Publish the entire database to all clients
blaze-html-templates        1.0.4  Compile HTML templates into reactive UI with Meteor Blaze
check                       1.2.1  Check whether a value matches a pattern
deanius:promise             3.1.3  Utilities for Promise-based wrappers, method calls, helpers and HTTP in Meteor
ecmascript                  0.4.3  Compiler plugin that supports ES2015+ in all .js files
es5-shim                    4.5.10  Shims and polyfills to improve ECMAScript 5 support
flemay:less-autoprefixer    1.2.0  The dynamic stylesheet language + Autoprefixer
fortawesome:fontawesome     4.5.0  Font Awesome (official): 500+ scalable vector icons, customizable via CSS, Retina friendly
http                        1.1.5  Make HTTP calls to remote servers
insecure                    1.0.7  (For prototyping only) Allow all database writes from the client
jquery                      1.11.8  Manipulate the DOM using CSS selectors
juliancwirko:s-alert        3.1.4  Simple and fancy notifications / alerts / errors for Meteor
juliancwirko:s-alert-genie  3.1.3  Genie effect for s-alert - simple and fancy notifications / alerts for Meteor.
meteor-base                 1.0.4  Packages that every Meteor app needs
mobile-experience           1.0.4  Packages for a great mobile user experience
mongo                       1.1.7  Adaptor for using MongoDB and Minimongo over DDP
msavin:mongol               2.0.1  In-App MongoDB Editor.. now works better than ever!
mvrx:bluebird               0.0.1  Bluebird is a fully featured promise library with focus on innovative features and performance.
reactive-var                1.0.9  Reactive variable
semantic:ui                 2.1.8  Official Semantic UI Integration for Meteor
session                     1.1.5  Session variable
standard-minifier-css       1.0.6  Standard css minifier used with Meteor apps by default.
standard-minifier-js        1.0.6  Standard javascript minifiers used with Meteor apps by default.
tracker                     1.0.13  Dependency tracker to allow reactive callbacks
twbs:bootstrap              3.3.6  The most popular front-end framework for developing responsive, mobile first projects on the web.

#3

Ok, one part of the puzzle is that I have to use this import statement

import 'meteor/mvrx:bluebird';

But apparently I still don’t use Bluebird, because the map method is not available…

current code

import { Meteor } from 'meteor/meteor';
import { http } from 'meteor/meteor';
import { Apps, TemplateApps } from '/imports/api/apps.js';
import { Streams } from '/imports/api/streams.js';
import { config } from '/imports/api/config.js'; 
import { engineConfig } from '/imports/api/config.js'; 
import { certs } from '/imports/api/config.js'; 
import {Customers} from '/imports/api/customers.js'; ;

var fs = require('fs');
var qsocks = require('qsocks');
var QRS = require('qrs');
import 'meteor/mvrx:bluebird';
var qrs = null;
var generatedAppGuid = '';




function getApps(){
	console.log('server: getApps');
	return qsocks.Connect(engineConfig).then(function(global) {

  //We can now interact with the global class, for example fetch the document list.
  //qsocks mimics the Engine API, refer to the Engine API documentation for available methods.
  global.getDocList().then(function(docList) {

  	// docList.forEach(function(doc) {
  	// 	console.log(doc.qDocName);
  	// });
  	return docList;
  });

});
	
};


/*
//	//for each customer
	//create stream if not already exist
	//copy app
	//publish to stream
	//add 'generated' tag
	*/
	function generateStreamAndApp (customers) {
		console.log('METHOD called: generateStreamAndApp for the template apps as stored in the database of the fictive OEM');

		var templateApps = TemplateApps.find().fetch();
	if(!TemplateApps.find().count()){//user has not specified a template
		throw new Meteor.Error('No Template', 'user has not specified a template for which apps can be generated');
	} 
	if(!customers.length){ // = 0
		throw new Meteor.Error('No customers', 'user has not specified at least one customer for which an app can be generated');
	} 

//FOR EACH TEPMPLATE
var generationEndedPromise =  Promise.all(Promise.map(templateApps, function(templateApp){
	// console.log('the current template app: ', templateApp.name);

	//FOR EACH CUSTOMER
	 return Promise.all(Promise.map(customers, function(customer){	
	// return Promise.all(_.map(customers, function(customer){	
		console.log('############## START CREATING THE TEMPLATE '+templateApp.name+' FOR THIS CUSTOMER: '+customer.name);

		var stream = Streams.findOne({name:customer.name});  //Find the stream for the name of the customer in Mongo, and get his Id from the returned object
		if(stream){
			var streamId = stream.id;
		}
		var myPromise = new Promise(function(resolve, reject) {
			if(!streamId){ 
				console.log('No stream for customer exist, so create one: '+customer.name);
				createStream( customer.name)
				.then(
					function fulfilled (result) {
						// console.log('stream create promosi fulfilled, result of create stream promise', result);
						streamId = result.id;
						resolve('created stream with id '+result.id);
					},
					function Rejected (error){
						// console.error('Promise Rejected: Error when trying to copy the app', error);
						reject('Promise Rejected: Error when trying to create a stream');
					})
			} else{
				// console.log('No need to create a stream, because it already exists: '+Streams.findOne({name:customer.name}).count()+' time(s)');
				resolve('No need to createa a stream, already exists'+Streams.find({name:customer.name}).count()+' time(s)');
			} 
		})
		.then(function(resultOfStreamStep){ //Copy the APP
			console.log('STEP 2 COPY the app: result Of create Stream Step: ', resultOfStreamStep);
			console.log('Now calling copy app for customer '+customer.name+' and template app: '+templateApp.name);
			return copyApp(templateApp.guid, customer.name+' - ' + templateApp.name)
		})
		// .then(function(appGuid){ //Publish into streamId
		// 	console.log('STEP 3 PUBLISH: APP HAS BEEN COPIED AND HAS RECEIVED GUID', appGuid);
		// 	return publishApp(appGuid, templateApp.name, streamId) //return publishApp(appGuid, templateApp.name+' - ' +customer.name , streamId)
		// })
		.then(function(){
			console.log('############## FINISHED CREATING THE TEMPLATE '+templateApp.name+' FOR THIS CUSTOMER: '+customer.name);
			console.log('	');
		})		
		.catch(function(err) {
			console.error(err);
			// throw new Meteor.Error('Catch error app generation chain: App generation failed', 'err');
		}).done();	
		return myPromise;

	}, { concurrency: 1 })) //each customer Promise.all
	}) //each template
	) //promise all generation total

return generationEndedPromise;
};


function copyApp (guid, name) {
	// console.log('Copy template: '+guid+' to new app: '+name);
	check(guid, String);
	check(name, String);

	return new Promise(function(resolve, reject){ 
		HTTP.call( 'post', 'http://'+config.host+'/'+config.virtualProxy+'/qrs/app/'+guid+'/copy?name='+name+'&xrfkey='+config.xrfkey, 
		{
			headers: {
				'hdr-usr' : config.headerValue,
				'X-Qlik-xrfkey': config.xrfkey
			}
		}, function( error, response ) {
			if ( error ) {
				console.error('error app copy',  error );
				throw new Meteor.Error('error app copy', error)
				reject(error);
			} else {
				// console.log('Copy app:  HTTP request gave response', response.data );
				console.log('Copy app HTTP call success:  the generated guid: ', response.data.id);				
				resolve(response.data.id); //return app Guid
			}
		});
	})
};

function publishApp (appGuid, appName, streamId) {
	console.log('Publish app: '+appName+' to stream: '+streamId);
	check(appGuid, String);
	check(appName, String);
	check(streamId, String);

	return new Promise(function(resolve, reject){ 
		HTTP.call( 'put', 'http://'+config.host+'/'+config.virtualProxy+'/qrs/app/'+appGuid+'/publish?name='+appName+'&stream='+streamId+'&xrfkey='+config.xrfkey, 
		{
			headers: {
				'hdr-usr' : config.headerValue,
				'X-Qlik-xrfkey': config.xrfkey
			}
		}, function( error, response ) {
			if ( error ) {
				console.error('error publishApp',  error );
				throw new Meteor.Error('error publish App', error)
				reject(error);
			} else {
				// console.log( response );
				resolve('publishApp success');
			}
		});
	})
	
};


function deleteApp (guid) {
	return HTTP.call( 'DELETE', 'http://'+config.host+'/'+config.virtualProxy+'/qrs/app/'+guid+'?xrfkey='+config.xrfkey, 
	{
		headers: {
			'hdr-usr' : config.headerValue,
			'X-Qlik-xrfkey': config.xrfkey
		}
	}, function( error, response ) {
		if ( error ) {
			console.error( error );
			throw new Meteor.Error('error app delete', error)
		} else {
			console.log( response );
			return response;
		}
	});
};

function deleteStream (guid) {
	return HTTP.call( 'DELETE', 'http://'+config.host+'/'+config.virtualProxy+'/qrs/stream/'+guid+'?xrfkey='+config.xrfkey, 
	{
		headers: {
			'hdr-usr' : config.headerValue,
			'X-Qlik-xrfkey': config.xrfkey
		}
	}, function( error, response ) {
		if ( error ) {
			console.error( error );
			throw new Meteor.Error('error stream delete', error)
		} else {
			console.log( response );
			return response;
		}
	});
};

function createStream (name) {
	console.log('create the stream with name', name);
	var myPromise = qrs.post('/qrs/stream', null,  {"name": name})
	.catch(err => {
		console.log(err);
		throw new Meteor.Error(err)
	})
	return myPromise
};

function getStreams () {
	return qrs.get('/qrs/stream/full');
};

Meteor.methods({  
	generateStreamAndApp (customers) {
		check(customers, Array);
		generateStreamAndApp(customers)
		.then(
			function fulfilled (result) {
				console.log('generation promise fulfilled, result of promise', result);
				// resolve('Generation success ');
				return 'Generation success';
			},
			function Rejected (error){
				console.error('Promise Rejected: Error when trying generate the apps', error);
				throw new Meteor.Error('Generation failed','Promise Rejected: Error when trying to generate the apps');
			})
	},
	getApps () {
		return new Promise((resolve, reject) => {
			qsocks.Connect(engineConfig)
			.then(function(global) {
				global.getDocList().then(function(docList) {
					resolve(docList) ;
				});
			})
		})
		.catch(err => {
			throw new Meteor.Error(err)
		})
	},
	copyApp (guid, name) {
		check(guid, String);
		check(name, String);
		return copyApp(guid,name);
	},
	deleteApp (guid) {
		check(guid, String);
		return deleteApp(guid);
	},
	deleteStream (guid) {
		check(guid, String);
		return deleteStream(guid);
	},
	countApps(){
		return qrs.get('/qrs/app/count');
	},
	countStreams(){
		return qrs.get('/qrs/stream/count');
	},
	createStream (name) {
		return createStream(name);
	},
	getStreams () {
		return getStreams();
	},
	getSecurityRules () {
		return getSecurityRules();
	},
	removeAllCustomers: function() {
		return Customers.remove({});
	},
	updateAppsCollection() {
		console.log('Method: update the local mongoDB with fresh data from Qlik Sense');

		try {
			Apps.remove();
		}
		catch (error) { throw new Meteor.Error('Unable to remove apps from collection',error.message) };

		var myPromise = qrs.get('/qrs/app/full')
		.then(
			function fulfilled (docList) {
				try {
					console.log('try to insert document array into mongo');
					docList.forEach(doc => {
						Apps.insert(doc);
						console.log('inserted document ', doc.qDocName);
					});
				}
				catch (error) { console.log(error) }

			}, function Rejected (error) {
				console.error('uh oh: ', error);   // 'uh oh: something bad happened’
			}).catch(function(error) {
				console.log('Caught!', error);
				throw new Meteor.Error('Unable to get streams from Sense', error.message);
			});
		}
	});

Meteor.startup(() => {
	qrs = new QRS(config);
});




//CODE WITH NPM QRS, THAT GENERATES DOUBLE APPS
// function copyApp (guid, name) {
// 	console.log('Copy template: '+guid+' to new app: '+name);
// 	check(guid, String);
// 	check(name, String);
// 	return qrs.post('/qrs/app/'+guid+'/copy', [{"key": "name", "value": name}])
// 	.then(
// 		function fulfilled (result) {
// 			console.log('result of copy app promise', result);
// 			return result;
// 		},
// 		function Rejected (error){
// 			console.error('Promise Rejected: Error when trying to copy the app', error);
// 			throw new Meteor.Error('App copy failed', 'App copy failed');
// 		})
// };


// return 
	// qsocks.Connect(engineConfig)
	// .then(function(global) {
	// 	console.log(global);
	// 	return global.getDocList()
	// }).then(function(docList){
	// 	console.log('DE DOC LIST IS: ', docList);
	// 	return docList;
	// })

#4

ok, that also did not work, so I tried to install it via NPM that worked better. I now seem to use bluebird, because my map function is available…

var Promise = require("bluebird");

but I have the bindenvironment error again, when I want to copy an app in a http call in a function that returns a promise

  • how can I put a promise into a meteor.wrapASync?

#5

Here’s some cut-down server-side demo code which uses Bluebird promises to fetch REST data and insert into a MongoDB collection using a Meteor method:

import { Meteor } from 'meteor/meteor';
import { Mongo } from 'meteor/mongo';
import { People } from '/imports/api/People';
import { HTTP } from 'meteor/http';
import Promise from 'bluebird';

const peopleCollection = People.rawCollection();

function httpGet(url) {
  return new Promise((resolve, reject) => {
    HTTP.get(url, (error, result) => {
      if (error) reject(error);
      resolve(result.data);
    });
  });
}

function peopleInsert(doc) {
  return new Promise((resolve, reject) => {
    peopleCollection.insert(doc, (error, result) => {
      if (error) reject(error);
      resolve(result);
    });
  });
}

Meteor.methods({
  updateCollection() {
    httpGet('http://jsonplaceholder.typicode.com/users').then(docs => {
      return Promise.map(docs, doc => {
        return peopleInsert(doc);
      });
    }).catch(err => {
      throw new Meteor.Error('oops', 'something bad happened');
    });
  },
});