I've written an R function in my package which returns a data frame. I'd like to call my function from javascript and use it to populate a table. I am able to successfully call the function using the ocpu/test interface and get back JSON.
I'm looking for a minimal example of how to do it with ocpu.rpc. I was thinking it could be finding the leading rows of the faithful data set using head: e.g. head(faithful). However, I think that the ocpu.rpc request can't be used with data already in R.
Based on the documentation, I thought the code should be:
ocpu.seturl("http://public.opencpu.org/ocpu/library/mylib/R");
var req = ocpu.rpc("func", { x : "param" }, function(obj) { return obj });
But req is undefined when I inspect it. What am I missing?
Related
I have a Meteor Helper that does a GET request and am supposed to get response back and pass it back to the Template, but its now showing up the front end. When I log it to console, it shows the value corerctly, for the life of mine I can't get this to output to the actual template.
Here is my helper:
UI.registerHelper('getDistance', function(formatted_address) {
HTTP.call( 'GET', 'https://maps.googleapis.com/maps/api/distancematrix/json? units=imperial&origins=Washington,DC&destinations='+formatted_address+'&key=MYKEY', {}, function( error, response ) {
if ( error ) {
console.log( error );
} else {
var distanceMiles = response.data.rows[0].elements[0].distance.text;
console.log(response.data.rows[0].elements[0].distance.text);
return distanceMiles;
}
});
});
In my template I pass have the following:
{{getDistance formatted_address}}
Again, this works fine and shows exactly what I need in the console, but not in the template.
Any ideas what I'm doing wrong?
I posted an article on TMC recently that you may find useful for such a pattern. In that article the problem involves executing an expensive function for each item in a list. As others have pointed out, doing asynchronous calls in a helper is not good practice.
In your case, make a local collection called Distances. If you wish, you can use your document _id to align it with your collection.
const Distances = new Mongo.collection(); // only declare this on the client
Then setup a function that either lazily computes the distance or returns it immediately if it's already been computed:
function lazyDistance(formatted_address){
let doc = Distances.findOne({ formatted_address: formatted_address });
if ( doc ){
return doc.distanceMiles;
} else {
let url = 'https://maps.googleapis.com/maps/api/distancematrix/json';
url += '?units=imperial&origins=Washington,DC&key=MYKEY&destinations=';
url += formatted_address;
HTTP.call('GET',url,{},(error,response )=>{
if ( error ) {
console.log( error );
} else {
Distances.insert({
formatted_address: formatted_address,
distanceMiles: response.data.rows[0].elements[0].distance.text
});
}
});
}
});
Now you can have a helper that just returns a cached value from that local collection:
UI.registerHelper('getDistance',formatted_address=>{
return lazyDistance(formatted_address);
});
You could also do this based on an _id instead of an address string of course. There's a tacit assumption above that formatted_address is unique.
It's Meteor's reactivity that really makes this work. The first time the helper is called the distance will be null but as it gets computed asynchronously the helper will automagically update the value.
best practice is not to do an async call in a helper. think of the #each and the helper as a way for the view to simply show the results of a prior calculation, not to get started on doing the calculation. remember that a helper might be called multiple times for a single item.
instead, in the onCreated() of your template, start the work of getting the data you need and doing your calculations. store those results in a reactive var, or reactive array. then your helper should do nothing more than look up the previously calculated results. further, should that helper be called more times than you expect, you don't have to worry about all those additional async calls being made.
The result does not show up because HTTP.call is an async function.
Use a reactiveVar in your case.
Depending on how is the formated_address param updated you can trigger the getDistance with a tracker autorun.
Regs
Yann
In Meteor, how do I properly return a value from a property (in this case response) from a collection so that I can send it to a data propert? I have tried the following function:
Responses: function(answer) {
return Responses.findOne({answerId: answer.hash.answer});
}
Which I call in the spacebars template as:
data-selected="{{Responses answer=_id}}
When I look at the HTML it says that the data-selected="[object object]" which is not super surprising but I can't figure out how to return just the response value from the match. I can add .response onto the end and it works but gives an expected 'undefined' error I know that it is not reactive. I have seen people use wrapasync but that was for methods, not subscriptions. I should note that there are several responses, so the code would have to be suitable inside a #for loop of answers which the responses variable is keeping track of the input from each user separately.
Thanks!
I'm not sure about data-selected="{{Responses answer=_id}}". Since you're already inside a for loop your html code can simply look like this:
data-selected="{{Responses}}"
Inside your helper function you can then say:
var myResponse = Responses.findOne({answerId: this._id}).response;
if (myResponse != null){
return myResponse;
else {
return "";
}
When the page is still loading and the data is not yet available, myResponse is still null, so the helper returns the empty string "". Shortly thereafter the data becomes available and your data gets returned, without any error in your console.
I've got a Firebase with a simple bit of data:
There's a list of "players", each with a self-generated GUID, and each containing a value "Count". At my request (e.g. using once()), I want to be able to query the players sorted by the Count value. So, based on the Firebase documentation, I'm using orderByChild(), but it always comes up as undefined when I run the code:
var fb = new Firebase("https://morewhitepixels.firebaseio.com/");
fb.child("players").orderByChild("Count").once("value",function(data) {
// do something with data
});
But this code always returns Uncaught TypeError: undefined is not a function pointing to that second line of code.
What am I missing?
I'm not sure what you do inside the callback, but this works fine:
fb.child("players").orderByChild("Count").once("value",function(data) {
console.log(data.val());
});
Keep in mind that the data parameter is not the actual data yet. It's a DataSnapshot on which you have to call val() first.
You'll probably want to loop through the children, which you can do like this:
fb.child("players").orderByChild("Count").once("value",function(data) {
data.forEach(function(snapshot) {
console.log(snapshot.val().Count);
});
});
The above example prints out all your children in the order you requested:
120320
181425
185227
202488
202488
202488
202488
245197
245197
487320
Alternatively you can use on('child_added' instead:
fb.child("players").orderByChild("Count").on("child_added",function(snapshot) {
console.log(snapshot.val().Count);
});
I am writing an app that involves creating multiple subsets of the same collection, and publishing them under different record sets following this example.
Using this principle, I am creating ad hoc record sets. The publish code is in a method that gets called per template:
//Template
Template.item._item = function() {
Meteor.call('publishMethod', foo);
Meteor.subscribe('name-'+foo);
return someFunction(foo);
}
//Method
Meteor.methods({
'publishMethod' = function(foo) {
Meteor.publish('name-'+foo, function() { someFunction(foo); });
});
});
//Common area
someFunction = function(foo) {
return Collection.find({'foobar' : foo});
}
In this example, someFunction() sits in common area between client and server. someFunction() returns a subset of a collection based on foo.
I have some questions regarding the above approach:
When a method is called with the same foo value, Meteor prints "Ignoring duplicate publish named 'name-foo'". Is there any way to check if a record set exists?
There is concern that these record sets will continue to be published and not release memory. Are these record sets client side only? Or will they accumulate on the server?
This is the best approach I have found for dealing with multiple, complex queries on the same large dataset, and allows for specific fields to be sent per request and page. I am however open to suggestions.
Thanks in advance.
Just having some issues with building a function using nodeJS. It doesn't seem to be returning the value, and I have a feeling its due to the asynchronous nature of the function call. Any help would be really appreciated!
sendFilesToDB is sent an array (from fs.readdir) of files to be processed. The files' content is used to construct a SQL query. Once successfully inserted, the file is deleted. But the fileToQuery function does not return a string at all (gives a 'Argument must be a string' error).
fileToQuery is returning void, because it says:
function fileToQuery(filePath) {
do_something(...);
}
That return statement you have isn't returning from filesToQuery but from the anonymous function you defined it in.
You need to rewrite your fileToQuery function to take an extra argument (perhaps resultCallback) and instead of returning your sql string, you do:
return resultCallback("INSERT IGNORE ....");
You'll then call it like this:
fileToQuery(file,function(query){
client.query(query, function(err, results) {
fs.unlink(file, function(err) {
sendFilesToDB(files);
});
});
});
By the way: This is called "continuation passing style" and can be done in any language that supports anonymous functions. What you asked for is called a callable continuation, but not very many languages have them. If you're interested in learning about them you should try picking up scheme.