how to get query parameter in action2 in sails - rest

I dont know how to set up route according to REST for the search request url like this
localhost:1337/system?id=10
After that, how can we get parameter from the above request in action 2 like this
action2(inputs,exits)
I want to follow best practice for web api in sails. Please hint me to solve and recommend any handy documents.
Thanks in advance

For the Actions2 format, you'd use inputs.id, after properly defining the inputs, of course. For more information, consult the documentation on Actions and Controllers. This would need more finishing, but it gets your input and a function. You'd want to add in your exits, and some real logic, of course, and probably some decent descriptions.
module.exports = {
inputs: {
id: {
type: 'number',
required: true
}
},
exits: {
success: { ... },
error: { ... }
},
fn: async function (inputs, exits) {
var myId = inputs.id;
return exits.success(myId);
}
}

Related

Meteor onRendered function and access to Collections

When user refresh a certain page, I want to set some initial values from the mongoDB database.
I tried using the onRendered method, which in the documentation states will run when the template that it is run on is inserted into the DOM. However, the database is not available at that instance?
When I try to access the database from the function:
Template.scienceMC.onRendered(function() {
var currentRad = radiationCollection.find().fetch()[0].rad;
}
I get the following error messages:
Exception from Tracker afterFlush function:
TypeError: Cannot read property 'rad' of undefined
However, when I run the line radiationCollection.find().fetch()[0].rad; in the console I can access the value?
How can I make sure that the copy of the mongoDB is available?
The best way for me was to use the waitOn function in the router. Thanks to #David Weldon for the tip.
Router.route('/templateName', {
waitOn: function () {
return Meteor.subscribe('collectionName');
},
action: function () {
// render all templates and regions for this route
this.render();
}
});
You need to setup a proper publication (it seems you did) and subscribe in the route parameters. If you want to make sure that you effectively have your data in the onRendered function, you need to add an extra step.
Here is an example of how to make it in your route definition:
this.templateController = RouteController.extend({
template: "YourTemplate",
action: function() {
if(this.isReady()) { this.render(); } else { this.render("yourTemplate"); this.render("loading");}
/*ACTION_FUNCTION*/
},
isReady: function() {
var subs = [
Meteor.subscribe("yoursubscription1"),
Meteor.subscribe("yoursubscription2")
];
var ready = true;
_.each(subs, function(sub) {
if(!sub.ready())
ready = false;
});
return ready;
},
data: function() {
return {
params: this.params || {}, //if you have params
yourData: radiationCollection.find()
};
}
});
In this example you get,in the onRendered function, your data both using this.data.yourData or radiationCollection.find()
EDIT: as #David Weldon stated in comment, you could also use an easier alternative: waitOn
I can't see your collection, so I can't guarantee that rad is a key in your collection, that said I believe your problem is that you collection isn't available yet. As #David Weldon says, you need to guard or wait on your subscription to be available (remember it has to load).
What I do in ironrouter is this:
data:function(){
var currentRad = radiationCollection.find().fetch()[0].rad;
if (typeof currentRad != 'undefined') {
// if typeof currentRad is not undefined
return currentRad;
}
}

Sencha Touch: How to build a restful proxy url syntax?

Defined as a model and its associations, I wish the http calls to follow best practices of restful. For example, if I make the call
user.posts();
I wish to run a call http defined as
users/1/posts
If a call is then put on post with id 32 then the url of reference must be
users/1/posts/32
So I want to avoid using the filter property as is the default for a get
/posts.php?filter=[{"property":"user_id","value":1}]
This is because the api rest are already defined and I can not change them.
I would like to build a minimally invasive solution and reading on various forums the best way is to do an ovveride the method buildURL the proxy rest but was not able to retrieve all the data needed to build the final URL. Can anyone give me an example?
thanks
Try the following:
window.serverUrl = "192.168.1.XX"
var service = "login.php"
var dataTosend: {
username:"xx",
password: "yy"
}
var methode:"POST" / "GET"
this.service(service,methode,dataTosend,onSucessFunction,onFailureFunction);
onSucessFunction: function(res) {
alert("onSucessFunction"):
},
onFailureFunction: function(res) {
alert("onFailureFunction"):
},
service: function(svc, callingMethod, data, successFunc, failureFunc) {
Ext.Ajax.request({
scope: this,
useDefaultXhrHeader: false,
method: callingMethod,
url: window.serverUrl + svc,
params: data,
reader: {
type: 'json'
},
failure: failureFunc,
success: successFunc
});
I hope this will solve your problem...

how to resolve optional url path using ng-resource

There are restful APIs, for instance:
/players - to get list for all players
/players{/playerName} - to get info for specific player
and I already have a function using ng-resource like:
function Play() {
return $resource('/players');
}
Can I reuse this function for specific player like:
function Play(name) {
return $resource('/players/:name', {
name: name
});
}
so I want to...
send request for /players if I didn't pass name parameter.
send request for /players/someone if I passed name parameter with someone
Otherwise, I have to write another function for specific play?
Using ngResource it's very, very simple (it's basically a two-liner). You don't need even need to create any custom actions here*.
I've posted a working Plunkr here (just open Chrome Developer tools and go to the Network tab to see the results).
Service body:
return $resource('/users/:id/:name', { id:'#id', name: '#name' })
Controller:
function( $scope, Users ){
Users.query(); // GET /users (expects an array)
Users.get({id:2}); // GET /users/2
Users.get({name:'Joe'}); // GET /users/Joe
}
of course, you could, if you really wanted to :)
This is how I did it. This way you don't have to write a custom resource function for each one of your endpoints, you just add it to your list resources list. I defined a list of the endpoints I wanted to use like this.
var constants = {
"serverAddress": "foobar.com/",
"resources": {
"Foo": {
"endpoint": "foo"
},
"Bar": {
"endpoint": "bar"
}
}
}
Then created resources out of each one of them like this.
var service = angular.module('app.services', ['ngResource']);
var resourceObjects = constants.resources;
for (var resourceName in resourceObjects) {
if (resourceObjects.hasOwnProperty(resourceName)) {
addResourceFactoryToService(service, resourceName, resourceObjects[resourceName].endpoint);
}
}
function addResourceFactoryToService (service, resourceName, resourceEndpoint) {
service.factory(resourceName, function($resource) {
return $resource(
constants.serverAddress + resourceEndpoint + '/:id',
{
id: '#id',
},
{
update: {
method: 'PUT',
params: {id: '#id'}
},
}
);
});
}
The nice thing about this is that it takes 2 seconds to add a new endpoint, and I even threw in a put method for you. Then you can inject any of your resources into your controllers like this.
.controller('homeCtrl', function($scope, Foo, Bar) {
$scope.foo = Foo.query();
$scope.bar = Bar.get({id:4});
}
Use Play.query() to find all players
Use Play.get({name:$scope.name}) to find one player

Angular service not updating on model change

In may app I have a service which holds my tasks:
app.factory('Tasks', function () {
var tasks = [];
return {
getAll: function () { return tasks; },
addOne: function (task) { tasks.push(task); },
openBy: function(owner) {
return _.where(tasks, {owner: owner, status: 'open'});
},
doneBy: function(owner) {
return _.where(tasks, {owner: owner, status: 'closed'});
},
};
});
I then show, per owner, either their open tasks or closed tasks.
The problem is that when I update the tasks by using Tasks.addOne(task); the views that use Tasks.openBy(owner) don't get updated. The ones that use Tasks.getAll() do.
Is this because I am returning a new array? If so is there a way of telling the controller to update what it has? Or am I just doing this entirely wrong in the first place and is there a better way to do it?
Any help would be greatly appreciated.
Matthew
What you could do is to call the openBy function in the controller (or directive) rather than in the view and wrap it into a $scope.$watch invocation. As an example:
// Controller body
app.controller('TasksCtrl', function($scope, Tasks) {
$scope.allTasks = Tasks.getAll();
$scope.$watch('allTasks', function() {
// Assume owner is the user and it's initialised somewhere above
$scope.ownedTasks = tasks.openBy(owner);
}, true);
});
This should work, even though I think that it should be possible to do something more elegant maybe!

Incrementally update Kendo UI autocomplete

I have a Kendo UI autocomplete bound to a remote transport that I need to tweak how it works and am coming up blank.
Currently, I perform a bunch of searches on the server and integrate the results into a JSON response and then return this to the datasource for the autocomplete. The problem is that this can take a long time and our application is time sensitive.
We have identified which searches are most important and found that 1 search accounts for 95% of the chosen results. However, I still need to provide the data from the other searches. I was thinking of kicking off separate requests for data on the server and adding them the autocomplete as they return. Our main search returns extremely fast and would be the first items added to the list. Then as the other searches return, I would like them to add dynamically to the list.
Our application uses knockout.js and I thought about making the datasource part of our view model, but from looking around, Kendo doesn't update based on changes to your observables.
I am currently stumped and any advice would be welcomed.
Edit:
I have been experimenting and have had some success simulating what I want with the following datasource:
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: window.performLookupUrl,
data: function () {
return {
param1: $("#Input").val()
};
}
},
parameterMap: function (options) {
return {
param1: options.param1
};
}
},
serverFiltering: true,
serverPaging: true,
requestEnd: function (e) {
if (e.type == "read") {
window.setTimeout(function() {
dataSource.add({ Name: "testin1234", Id: "X1234" })
}, 2000);
}
}
});
If the first search returns results, then after 2 seconds, a new item pops into the list. However, if the first search fails, then nothing happens. Is it proper to use (abuse??) the requestEnd like this? My eventual goal is to kick off the rest of the searches from this function.
I contacted Telerik and they gave me the following jsbin that I was able to modify to suit my needs.
http://jsbin.com/ezucuk/5/edit