Get query string params using Restful / Resourceful / Flatiron - flatiron.js

I have the following node app using Restful / Resourceful / Flatiron:
app.js
var flatiron = require('flatiron'),
fixtures = require('./fixtures'),
restful = require('restful'),
resourceful = require('resourceful');
var app = module.exports = flatiron.app;
app.resources = {};
app.resources.Creature = fixtures.Creature;
app.use(flatiron.plugins.http, {
headers: {
'x-powered-by': 'flatiron ' + flatiron.version
}
});
app.use(restful);
app.start(8000, function(){
console.log(app.router.routes);
console.log(' > http server started on port 8000');
console.log(' > visit: http://localhost:8000/ ');
});
Here is the fixtures module:
fixtures.js
var fixtures = exports;
var resourceful = require('resourceful');
// // Create a new Creature resource using the Resourceful library //
fixtures.Creature = resourceful.define('creature', function () {
var self = this;
this.restful = true;
this.all = function (callback) {
console.log(this);
callback(null, "ok"); };
});
How can I access the request/query string parameters? E.g. if the route is /creatures?foo=bar
I came across this issue from the Github repo, but the comments imply there may be a more long winded method of obtaining this data?
I've been looking at the source code for resourceful and I don't see a clear way. Here is the line in question:
https://github.com/flatiron/resourceful/blob/master/lib/resourceful/resource.js#L379

The default versions listed via NPM Package Manager are out of date which caused some confusion.
See the Github issue here:
https://github.com/flatiron/restful/issues/33
Using package.json in combination with NPM install works with the version combinations:
"restful": "0.4.4",
"director": "1.1.x",
"resourceful": "0.3.x",
"director-explorer": "*"
With this newer version the url format now works in the style of:
/create/find?foo=bar
The method in question is can be found here:
https://github.com/flatiron/restful/blob/master/lib/restful.js#L506
At the time of writing the method looks as follows:
router.get('/' + entity + '/find', function () {
var res = this.res,
req = this.req;
preprocessRequest(req, resource, 'find');
resource.find(req.restful.data, function(err, result){
respond(req, res, 200, entity, result);
});
});
The key component being that req.restful.data is the parsed query string data.

Related

Falcor Router should return the value from external API

I am new to JavaScript frameworks and currently trying to setup a falcor router calling an external api (for now consider it as an express api app + mango db, hosted at 3000 port).
Now, I am able to use the request package (commented out lines) and successfully call the Express Api app (which returns obj.rating = 4). But I am unable to send this value from the falcor router instead of the hard-coded value "5".
Below is the falcor-router's server.js code:
app.use('/rating.json', falcorExpress.dataSourceRoute(function (req, res) {
return new Router([
{
route: "rating",
get: function() {
var obj;
// request('http://localhost:3000/rating/101', function (error, response, body) {
// obj = JSON.parse(body);
// console.log('rating:', obj.rating); // obj.rating = 4
// });
return {path:["rating"], value:"5"};
}
}
]);
}));
The below is the code for index.html:
<script>
function showRating() {
var model = new falcor.Model({source: new falcor.HttpDataSource('http://localhost/rating.json') });
model.
get("rating").
then(function(response) {
document.getElementById('filmRating').innerText = JSON.stringify(response.json,null, 4);
});
}
</script>
I also tried to look at the global variable declaration, synchronize http request calls, promises, then statements etc. But nothing seemed to work, clearly I am missing out something here - not sure what.
The router's get handler expects the return value to be a promise or an observable that resolves to a pathValue. To get your request against the db to work, simply return a promise that resolves to a pathValue, e.g.
return new Router([
{
route: "rating",
get: function() {
return request('http://localhost:3000/rating/101', function (error, response, body) {
return { path: ["rating", value: JSON.parse(body).rating };
});
}
}
]);

SAPUI5 - OData is not defined

I am trying send some data to sap gateway service.
I am using this example the method "save", but when I try do it in my code I get an error "OData is not defined"
Below is the method when I try do it.
handleConfirmationMessageBoxPress: function(oEvent) {
var bCompact = !!this.getView().$().closest(".sapUiSizeCompact").length;
MessageBox.confirm(
"Deseja confirmar a transferência?", {
icon: sap.m.MessageBox.Icon.SUCCESS,
title: "Confirmar",
actions: [sap.m.MessageBox.Action.OK, sap.m.MessageBox.Action.CANCEL],
onClose: function(oAction) {
if (oAction == "OK") {
var oParameters = {};
oParameters.loginfrom = this.getView().byId("multiInput").getValue();
oParameters.loginfrom = this.getView().byId("loginPara").getValue();
oParameters.loginfrom = this.getView().byId("datade").getValue();
oParameters.loginfrom = this.getView().byId("datapara").getValue();
OData.request({
requestUri : "http://<host name>:<port no>/sap/opu/odata/sap/ZMM_EMP_SRV/EmployeeSet",
method : "GET",
headers : {...}
},
function(data, response) {
...
var oHeaders = {
... };
OData.request({
requestUri : "http://<host name>:<port no>/sap/opu/odata/sap/ZMM_EMP_SRV/EmployeeSet",
method : "POST",
headers : oHeaders,
data:oParameters
},
function(data,request) {
MessageToast.show("Transferência realizada!");
location.reload(true);
}, function(err) {
MessageToast.show("A transferência falhou!");
});
}, function(err) {
var request = err.request;
var response = err.response;
alert("Error in Get — Request " + request + " Response " + response);
});
} else {
...
You are attempting to use the OData global object from the datajs library. This library is indeed shipped with OpenUI5, but IMO you should not use it directly (but use the methods of the OData model; there is no real guarantee that UI5 will continue shipping this third-party library in the future).
You are most likely getting the error because the library was not yet loaded by UI5. Libraries are generally lazily loaded by UI5, so you will have to request that UI5 loads it for you (in the tutorial that you have linked, it was loaded behind the scenes by the OData model). To do this, you can either use jQuery.sap.require (jQuery.sap.require("sap.ui.thirdparty.datajs")) or list the dependency inside your sap.ui.define call at the beginning of the controller (e.g. sap.ui.define(['sap/ui/thirdparty/datajs'], function(datajs){...})).
Later edit: you can also use the jQuery.sap.require("sap.ui.model.odata.datajs"); call, but the module was moved from there and it would effectively redirect you to the new location.
this is a very old example, and the used old techniques.
You should add this line to your code:
jQuery.sap.require("sap.ui.model.odata.datajs");
This should solve your oData is undefined problem.
In general you should read newer examples where the read() function of the odata model is used.

Invalid signature when trying to upload to Cloudinary

Using the Node integration provided by cloudinary_npm, I'm getting the following message back when I try to upload:
{ error: { message: 'Invalid Signature t7233823748278473838erfndsjy8234. String to sign - \'timestamp=1439054775\'.', http_code: 401 } }
I retrieve then pass my image to the backend like this:
$scope.previewFile = function() {
var file = document.querySelector('input[type=file]').files[0];
var reader = new FileReader();
if (file) {
reader.readAsDataURL(file);
} else {
preview.src = "";
}
reader.onloadend = function () {
base64img = reader.result;
preview.src = base64img;
console.log(base64img);
};
};
$scope.submitPic = function() {
$http.post('http://localhost:3000/story/pic', {img: base64img})
.success(function(data){
preview.src = "";
})
.error(function(err){
console.log(err);
});
};
Then in the back, I have the following configuration and routes, both straight from the docs:
var cloudinary = require("cloudinary");
var CLOUD_API_SECRET = require("../constants.js");
cloudinary.config({
cloud_name: 'some_cloud',
api_key: '63789865675995',
api_secret: CLOUD_API_SECRET
});
router.post('/pic', function(req, res, next) {
var img = req.body.img;
cloudinary.uploader.upload(img, function(result) {
});
res.status(200).send('ok');
});
Does anyone recognize what I might be doing wrong? I've been troubleshooting this for hours. I'm at a dead end.
make sure you have placed your cloudinary secret inside a ''(quote/inverted comma).make sure the resulting statement should mean :
var CLOUD_API_SECRET ='some_cloudinary_secret_xxx';
check this value in the js file from where you are fetching this value.
From Java level I fixed this issue by changing the time zone to America/New_York time:
Long time = new Long(System.currentTimeMillis() );
SimpleDateFormat sdf = new SimpleDateFormat();
sdf.setTimeZone(TimeZone.getTimeZone("America/New_York"));
Date date = new Date(sdf.format(new Date(time)));
long utcDateInMilliSeconds = date.getTime();
params.put("timestamp", new Long(utcDateInMilliSeconds/1000));
I had this very same error running similar code route on nodejs using cloudinary's sdk.
The issue turned out to be a typo within my API_SECRET.
Like Jeremy said, It's mostly typo or white space in your API secret.
Try to use your API secret directly in the configuration (not via variable)

Error: Unknown provider: aProvider <- a

I'm using AngularJS in a Ruby on Rails 3.2.8 project with assets.
When I load up my form which is using AngularJS on my development machine I don't have a problem. However when I load the same form up on my production server I get this error in the Javascript console:
Error: Unknown provider: aProvider <- a
I've tracked it back to my coffeescript file where I setup AngularJS for use within a form:
$ (event) ->
$("#timesheet_description").autocomplete({source: '/autocomplete/work_descs'})
# Create AngularJS module
app = angular.module 'timesheetApp', []
# Create a AngularJS controller
app.controller "TimesheetCtrl", ($scope) ->
$scope.costed_amount = 0
# Bind my module to the global variables so I can use it.
angular.bootstrap document, ["timesheetApp"]
If I comment all this out the page will load without errors and without AngularJS abilities.
Is the problem due to Rails assets compiling and minify?
Is there a way to fix this and still use coffeescript and Rails assets?
AngularJS, when using the style you're using right now (called pretotyping), uses the function argument names to do dependency injection. So yes, minification does break this completely.
The fix is simple, though. In every case where you need injection (are using '$xxx') variables, do this:
app.controller "TimesheetCtrl", ['$scope', ($scope) ->
$scope.costed_amount = 0
]
Basically, replace all function definitions with an array. The last element should be the function definition itself, and the first ones are the $names of the objects you want injected.
There's some more (albeit not clear enough) info on the docs.
If you miss the array notation somewhere , to locate this we need to modify the angular code little bit, but its very quick solution.
change is console.log("Array Notation is Missing",fn); ( line no 11 from function start)
Find out annotate function in angular.js (non-minified)
function annotate(fn) {
var $inject,
fnText,
argDecl,
last;
if (typeof fn == 'function') {
if (!($inject = fn.$inject)) {
$inject = [];
if (fn.length) {
console.log("Array Notation is Missing",fn);
fnText = fn.toString().replace(STRIP_COMMENTS, '');
argDecl = fnText.match(FN_ARGS);
forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg){
arg.replace(FN_ARG, function(all, underscore, name){
$inject.push(name);
});
});
}
fn.$inject = $inject;
}
} else if (isArray(fn)) {
last = fn.length - 1;
assertArgFn(fn[last], 'fn');
$inject = fn.slice(0, last);
} else {
assertArgFn(fn, 'fn', true);
}
return $inject;
}
To minify angular all you need is to do is to change your declaration to the "array" declaration "mode" for example:
From:
var demoApp= angular.module('demoApp', []);
demoApp.controller(function demoCtrl($scope) {
} );
To
var demoApp= angular.module('demoApp', []);
demoApp.controller(["$scope",function demoCtrl($scope) {
}]);
How to declare factory services?
demoApp.factory('demoFactory', ['$q', '$http', function ($q, $http) {
return {
//some object
};
}]);

How to parse a XML string in a Firefox addon using Add-on SDK

I am trying to create a FF AddOn that brings some XML data from a website. But I can't find a way to parse my RESPONSE. First I used DOMParser but I get this error:
ReferenceError: DOMParser is not defined.
Someone suggested to use XMLHttpRequest, because the parsing is done automatically but then I get this other error:
Error: An exception occurred. Traceback (most recent call last):
File
"resource://jid0-a23vmnhgidl8wlymvolsst4ca98-at-jetpack/api-utils/lib/cuddlefish.js",
line 208, in require
let module, manifest = this.manifest[base], requirer = this.modules[base]; TypeError: this.manifest is undefined
I really don't know what else to do. I must note that I am using the AddOn Builder to achieve this.
Below the code that doesn't seem to work.
Option 1:
exports.main = function() {
require("widget").Widget({
id: "widgetID1",
label: "My Mozilla Widget",
contentURL: "http://www.mozilla.org/favicon.ico",
onClick: function(event) {
var Request = require("request").Request;
var goblecontent = Request({
url: "http://www.myexperiment.org/search.xml?query=goble",
onComplete: function (response) {
var parser = new DOMParser();
var xml = parser.parseFromString(response.text, "application/xml");
var packs = xml.getElementsByTagName("packs");
console.log(packs);
}
});
goblecontent.get();
}
});
};
Option 2:
exports.main = function() {
require("widget").Widget({
id: "widgetID1",
label: "My Mozilla Widget",
contentURL: "http://www.mozilla.org/favicon.ico",
onClick: function(event) {
var request = new require("xhr").XMLHttpRequest();
request.open("GET", "http://www.myexperiment.org/search.xml?query=goble", false);
request.send(null);
if (request.status === 200) {
console.log(request.responseText);
}
}
});
};
DOMParser constructor isn't defined in the context of SDK modules. You can still get it using chrome authority however:
var {Cc, Ci} = require("chrome");
var parser = Cc["#mozilla.org/xmlextras/domparser;1"].createInstance(Ci.nsIDOMParser);
nsIDOMParser documentation.
That said, your approach with XMLHttpRequest should work as well. You used the new operator incorrectly however, the way you wrote it a new "require object" is being created. This way it should work however:
var {XMLHttpRequest} = require("xhr");
var request = new XMLHttpRequest();
Please consider using an asynchronous XMLHttpRequest object however, use request.onreadystatechange to attach your listener (the xhr module currently doesn't support other types of listeners or addEventListener).
If you use XMLHttpRequest (available via the xhr module) you can easily avoid the use of DOMParser. Bellow I provide an example supposing request is an XMLHttpRequest object which request is successfully completed:
Instead of:
var parser = new DOMParser();
var xmlDoc = parser.parseFromString(request.responseText, "application/xml");
Use:
var xmlDoc = request.responseXML;
An then you can:
var packs = xmlDoc.getElementsByTagName("packs");
console.log(packs);
Or whatever.

Resources