What I'm trying to do is described in great detail here:
Call a Server-side Method on a Resource in a RESTful Way
I have Ember Data's RESTAdapter working with my API, but now I want to give Ember.js a way to kick off various server-side actions using custom routes, such as /docs/1/share or /docs/1/activate. The former would possibly modify the record but the latter would not.
What's the best way to do this?
TIA!
Ember has jQuery baked in. In your controller:
actions: {
activate: function() {
var docId= this.get('id'), self= this;
Ember.$.ajax({
url: '/docs/%#/activate'.fmt(docId),
// your other details...
}).then(function(resolve) {
self.set('name', resolve.doc.name);
// process the result...
});
}
}
You can also use ic-ajax which is a nice wrapper around jQuery.ajax, you can see an example here using ix-ajax.
Related
I'm interested in using the HATEOAS principle of REST to reduce business logic in a SPA application. In a React-specific context, I'd like to know if there are challenges that make this impractical and, if not, what is a good strategy to follow?
Conceptual examples of using HATEOAS to remove business logic from the UI:
Delegating valid bank account actions to the REST service
Delegating role-based access control to the REST service
I've only found one link that suggests React/Flux is not compatible with a HATEOAS strategy, and no meaningful discussion elsewhere. Is it really not feasible in a React/Flux app? That SO post didn't get enough attention. Does anyone have a favorite or recommended approach for achieving success (with or without Flux or Redux)?
Someone gave a fairly detailed example of leveraging HATEOAS in the context of Angular. I'm looking for something similar for React.
Personally, I'm picturing the rel tag in hypermedia links controlling which JSX components are rendered (conditional JSX). Is that naive for a real-world React app? Perhaps conditionally rendered React components are too coarse-grained to be used this way?
I am assuming that hypermedia links are provided by a HAL implementation, or otherwise conform to the ATOM feed convention (RFC4287).
100% HATEOAS IS compatible with React & Flux, HATEOAS is compatible with Angular, HATEOAS is compatible with JQuery and even vanilla JS.
HATEOAS doesn't not impose any technical or implementation requirements on a consuming client.
HATEOAS is in fact simply a concept to which you can design your API (you can use one of several standards though like HAL)
Basically if you can call an API then you can implement a HATEOAS client.
So how to get there:
Step 1, how would you normally do an API call in React? Do it the same way.
Step 2, interrogate response.
Step 3, based on response, respond in the UI appropriately.
For example given a call to the order api /orders, I get the following response:
{
"_links": {
"self": { "href": "/orders" },
"next": { "href": "/orders?page=2" }
}
}
From this I can infer that next is a valid relation, and that if I go to that href I would in fact receive a second page of orders, so in this case in the UI show the next button.
However if I had received the following response:
{
"_links": {
"self": { "href": "/orders" },
}
}
Then I could infer that next is not a valid relation, and in my UI I should disabled or not display a next button.
There is no magic, it is simply a change in thinking, a new paradigm.
Before I spout off my most likely wrong/irrelevant answer, I just want to let you know that I just now read up on what HATEOAS is. That warning there, from what I've briefly read, HATEOAS seems to be mostly about the API telling you how to navigate through itself by providing you a link back to the resources that are relevant to the resource you had just requested.
That being the case, I don't see a reason why you can't implement dynamic url ajax calls in your actions that will alter your SPA's application state (i.e. Redux) based on what has been provided to you, however, you'll still need to have something to represent the state in a visual manner for all parts of your application. Here's a crude semi-pseudo and not very well thought-out representation of what I mean based loosely on your bank account example:
// our component file
import React from 'react'
import { makeAWithdrawl } from './actions'
export default React.createClass({
handleClick: function(e) {
e.preventDefault()
makeAWithdrawl(this.props.account.withdraw.href)
},
render: function () {
<div className="account">
<p className="account_number">{this.props.account.accountNumber}</p>
<p className="balance">{this.props.account.balance}</p>
<p><a href={this.props.account.deposit.href}>Deposit</a></p>
{this.props.account.withdraw ? <p><a onClick={this.handleClick}>Withdraw</a></p> : ''}
</div>
}
})
// our actions file
import store from 'store' // our redux store
import axios from 'axios' // an ajax library
export function makeAWithdrawl(url) {
return axios.post(url).then(function(resp){
store.dispatch({
type: 'MAKE_WITHDRAWL',
action: resp.data
}) // do your reducer stuff
})
}
Your application still knows what it's doing in the SPA, however, this will allow the API to direct you where to call to for whatever action needs to be performed. Hope it helps.
I'm new to Sails and seems that I cannot find an elegant way to use multiple layouts with sails v.10.
My site has two different sections: public website and admin side. I don't want to set the layout separately for every action for different controllers in the app's admin section. It seems that policies might be the way to handle this but for some reason it's not working and couldn't find details how to handle this from Sails's documentation or around the web.
I think the following way of doing it results in repetition:
module.exports = {
index: function(req, res){
res.view({ layout: 'layoutadmin' });
}
}
Any pointers?
Thanks,
J
res.locals.layout = 'layoutadmin';
This should work inside a policy. If it doesnt, problem is somewhere else.
In HTML, I would do routes.ControllerName.Method to present a link to user that will automatically change when I rename the URLs. How should I do it in links in javascript ajax query URLs?
You need to look up Javascript Reverse Routing in the docs.
Basically, a Play reverse router will generate equivalent JS functions (namespaced per controller) to obtain an URL given the appropriate parameters for each particular action. You then define a separate route to load that JS whenever you need access to those URLs.
I personally find that typing the URL in the JavaScript file makes it the much more readable.
You didn't supply any code so I've included some of my own.
In my one of my Angular factories, I would have something like this
var mainroute = "/api/security";
var submitLogin = function (login) {
return $http({
method: "POST",
url: mainroute + "/login",
data: login
});
};
Then in my route file, I would only need to add the route.
# API
POST /api/security/login controllers.Security.Login()
Using the mainroute variable I can quickly change the parent URL to all the methods.
Short question, tried finding an IRC for sails for such a quick one but got lost so here goes. I have a controller with a route of '/userposts'. I know sails offers some default REST-like functionality without backend code needed but what if I want to overwrite the default POST action what would I do?
I'm forced to write a POST route such as post /userposts/create or I can overwrite the default action and post straight to /userposts which will identify my overwriting and execute it.
I hope I'm making sense. I basically want to create a custom POST route and be able to
socket.post('/userposts', {title: "Foo", content: "Bar"}, function(response){});
I tried with create but it doesn't get executed on a post to /userposts
Sails.js provides blueprints out of the box.
These blueprints provide you with the following CRUD routes that are enabled by default
/:controller/find/:id?
/:controller/create
/:controller/update/:id
/:controller/destroy/:id
To modify the default functionality for your controllers, look at the settings in config/controllers.js
Your routes are defined within config/routes.js, in your case you have a model UserPosts and a corresponding controller named UserPostsController.
In your UserPosts controller, create a function createPost and specify the route(s) to this method
'POST /userposts/create': 'UserPostsController.createPost'
which is shorthand for
'POST /userposts/create': {
controller: 'userposts',
action: 'createPost'
}
you can also override the /:controller route
'POST /userposts': 'UserPostsController.createPost'
These routes will map any POST requests made to the createPost function.
For more information, be sure to check out the Sails.js documentation
I need to call a receive activity in my workflow from javascript passing the parameters as json and i need the response as json format too..
I tried everything that i found but nothing works.
Hope you can help me... thanks
The Receive activity only supports SOAP requests and at the moment there is no way to do REST style communications with it. One work around would be to create a regular WCF REST service as a wrapper for your workflow and have the JavaScript client go through this wrapper.
Thank you very much for your answer. I will do it, i found this page "http://msmvps.com/blogs/theproblemsolver/" and now i know how keep the receive activities because i was not clear if i should remove them from my workflow or keep it... Here is a litle piece of code that show how to.
var factory = new ChannelFactory(new BasicHttpBinding(),
new EndpointAddress("http://localhost:9199/Service1.xamlx"));
var proxy = factory.CreateChannel();
var response = proxy.GetData(new GetDataRequest() { Value = 42 });
Console.WriteLine(response.Value);