I'm using Stripe grails plugin in my application and I'm getting the below error:
Class:groovy.lang.MissingPropertyExceptionMessage:No such property: Stripe for class: com.myApp.app.SubscriptionRequestController
Here is my action:
def charge(String stripeToken, Double amount) {
Stripe.apiKey = grailsApplication.config.grails.plugins.stripe.secretKey
def amountInCents = (amount * 100) as Integer
def chargeParams = [
'amount': amountInCents,
'currency': 'usd',
'card': stripeToken,
'description': 'customer#sample.org'
]
def status
try {
Charge.create(chargeParams)
status = 'Your purchase was successful.'
} catch(CardException) {
status = 'There was an error processing your credit card.'
}
redirect(action: "confirmation", params: [msg: status])
return
}
i'm also getting the below error since i installed the plugin when i remove it i don't see it, it occurs while trying to access or refresh any view :
java.lang.RuntimeException: It looks like you are missing some calls to the r:layoutResources tag. After rendering your page the following have not been rendered: [head]
Try this:
in your main layout file e.g.: main.gsp, have the two additional both in body and head. Also, loads the stripe-v2 manually. No need to add it in web-app/js as the plugin itself already has it.
<html>
<head>
<g:javascript src="stripe-v2.js" />
<r:layoutResources/>
</head>
<body>
<g:layoutBody/>
<r:layoutResources/>
</body>
</html>
in config.groovy add:
grails.resources.modules = {
stripe {
dependsOn 'jquery'
resource url:'/js/stripe-v2.js', disposition: 'head', exclude:'minify'
}
}
Sample gsp (taken from the docs) but i added payment-errors as the source use it:
<stripe:script formName="payment-form"/>
<g:form controller="checkout" action="charge" method="POST" name="payment-form">
<div class="payment-errors"></div>
<div class="form-row">
<label>Amount (USD)</label>
<input type="text" size="20" autocomplete="off" id="amount" name="amount"/>
</div>
<stripe:creditCardInputs cssClass="form-row"/>
<button type="submit">Submit Payment</button>
</g:form>
I think the plugin itself did not support the current implementation of Grails Asset Pipeline.I think it is not compatible for grails 2.4.3 and above.
As it stands, you probably aren't importing the com.stripe.Stripe class which is why you're getting that particular message.
You don't need to attempt to manually assign the secret key to the Stripe class. Just define grails.plugins.stripe.secretKey in your Config.groovy and the plugin will handle the rest, as you can see in the plugin source.
Related
I'm working on a very basic Grails application in order to dip my toes into web development.
Unfortunately, I'm stuck at trying to display a collection within my MongoDB database using the <f:table>-field tag.... Because the tag somehow seems to be incompatible with the unique constraint of my domain class? Is there anything I can do?
Here's the error message:
There was an unexpected error (type=Internal Server Error, status=500).
Error processing GroovyPageView: [views/teaser/index.gsp:17] Error executing tag <f:table>: Exception thrown applying constraint [unique] to class [class com.test.site.Teaser] for value [true]: Cannot invoke "grails.gorm.validation.Constraint.isValid()" because "c" is null
My BootStrap contains two object instances for testing purposes; they seem to be working fine, since they appear in my MongoDB. Just to be safe, here is how I stored them:
new Teaser(imageUrl: "", teaserUrl: "", name: "mainTeaser", text: "").save()
new Teaser(imageUrl: "", teaserUrl: "", name: "footerTeaser", text: "").save()
Here's my domain class:
package com.test.site
class Teaser {
String imageUrl
String teaserUrl
String name
String text
static mapWith = "mongo"
static constraints = {
name blank: false
name unique: true
}
Here's the current state of my index.gsp (linked to my controller):
<!doctype html>
<html>
<head>
<meta name="layout" content="main">
<asset:stylesheet href="styles.css"/>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Teaser Details</title>
</head>
<body id="body">
<header class="header">
</header>
<main class="main">
<div class="container">
<section>
<f:table collection="${teaserList}"/>
</section>
</div>
</main>
<footer class="footer">
</footer>
</body>
</html>
Finally, here's my controller:
package com.test.site
class TeaserController {
static scaffold = Teaser
def index() {
def teaserList = Teaser.list()
render view: "index", model: [teaserList : teaserList]
}
I'm grateful for any help :)
I'm trying to use react_on_rails to build my first example with react and rails. I'm trying to save some data to the rails backend, using axios for the ajax.
here's my code:
import store from "../store/helloWorld";
import axios from "axios";
export const SAVE_NAME = "SAVE_NAME";
export function saveNameAction(name) {
return {
type: SAVE_NAME,
name
};
}
export function saveName(name) {
axios
.post("/hello_world", saveNameAction(name))
.then(function(response) {
console.log(response);
})
.catch(function(error) {
console.log(error);
});
}
and the component:
import PropTypes from "prop-types";
import React from "react";
import * as actions from "../actions/helloWorld";
export default class HelloWorld extends React.Component {
static propTypes = {
name: PropTypes.string.isRequired // this is passed from the Rails view
};
/**
* #param props - Comes from your rails view.
*/
constructor(props) {
super(props);
this.state = { name: this.props.name };
}
updateName(name) {
this.setState({ name: name });
}
handleSubmit(event) {
event.preventDefault();
actions.saveName(this.state.name);
}
render() {
return (
<div>
<h3>
Hellopp, {this.state.name}!
</h3>
<hr />
<form>
<label htmlFor="name">Say hello to:</label>
<input
id="name"
type="text"
value={this.state.name}
onChange={e => this.updateName(e.target.value)}
/>
<input
type="submit"
value="Submit"
onClick={event => this.handleSubmit(event)}
/>
</form>
</div>
);
}
}
The problem is that when I click the submit, my backend reports
Started POST "/hello_world" for ::1 at 2017-07-07 15:30:44 +0200
Processing by HelloWorldController#create as HTML
Parameters: {"type"=>"SAVE_NAME", "name"=>"Stranger", "hello_world"=>{"type"=>"SAVE_NAME", "name"=>"Stranger"}}
Can't verify CSRF token authenticity.
Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms)
ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
For one, I don't understand why the parameters seem to be passed twice, but that's not even generating a warning, so don't care for now.
The problem is that I don't see a way to obtain the CSRF tokens in my react code to use in the post requests
should I just disable CSRF? or is there a better way?
ActionController::InvalidAuthenticityToken
(ActionController::InvalidAuthenticityToken):
Rails handles CSRF attacks by appending authenticity_token to every Non-GET requests(POST,PUT/PATCH and DELETE). The error means you are not sending authencity_token in the request params, You should append an unique authenticity_token to the params, something like "authuenticity_token" => "BsfdgtZ1hshxgthjj" which should resolve the issue.
react_on_rails deals with this issue by providing two helpers. From the react_on_rails documentation:
Rails has built-in protection for Cross-Site Request Forgery (CSRF), see Rails Documentation. To nicely utilize this feature in JavaScript requests, React on Rails provides two helpers that can be used as following for POST, PUT or DELETE requests:
import ReactOnRails from 'react-on-rails';
// reads from DOM csrf token generated by Rails in <%= csrf_meta_tags %>
csrfToken = ReactOnRails.authenticityToken();
// compose Rails specific request header as following { X-CSRF-Token: csrfToken, X-Requested-With: XMLHttpRequest }
header = ReactOnRails.authenticityHeaders(otherHeader);
I found that react_on_rails has a helper system to handle CSRF tokens,
it basically uses:
<%= csrf_meta_tags %>
to add the csrf_token to the headers in the page as a meta
and then you can use:
import ReactOnRails from "react-on-rails";
export function saveNameAction(name) {
console.log("creating action " + name);
return {
authenticity_token: ReactOnRails.authenticityToken(),
type: SAVE_NAME,
name
};
}
to fetch it and use it.
I'm following along with the Angular/Rails tutorial at Thinkster and I've run into an issue which seems to be most likely be Angular-related. Everything works just fine until I get to the Angular Routing section. Simply put, the inline templates within the <script> tags do not load in the <ui-view></ui-view> element. I originally thought this may be due to having opened the page locally as a file rather than having it loaded from a server, but the same problem persists even after integrating Rails (using an older version of Sprockets, as pointed out in this similar but unrelated issue).
When I load the index page in either the browser as a file or as a URL when running the Rails server, I've inspected the HTML and, sure enough, the only thing it shows in the code are the divs and an empty <ui-view> element, indicating something just isn't adding up correctly. I've tried various things, including:
Using the newest version of ui-router (0.2.15 at this writing) rather than the version in the tutorial
Using <div ui-view></div> instead of <ui-view></ui-view>
Changing the value of 'url' in the home state to 'index.html', including using the full path to the file (file:///...)
Putting the contents of the inline <script> templates into their own files (without the <script> tags, of course) and specifying the 'templateUrl' field using both relative and full paths
Trying both Chrome and Firefox just to be extra certain
None of these things have worked, even when accessing http://localhost:3000/#/home when the Rails server is running after having integrated Angular into the asset pipeline in the Integrating the Front-end with the Asset Pipeline section of the tutorial. Indeed, the route loads but does not show anything more than a completely blank page with a lonesome and empty <ui-view> element when inspecting the HTML using Chrome's dev tools.
Given that the issue seems to occur even before the Rails portion, it does seem like something to do with Angular itself, but I've got no clue what's going on, especially since I've followed along to the letter.
I'm using Bower to manage the Angular dependencies and the HTML does show that the Angular javascript files in both the app/assets/javascripts directory and in the vendor/assets/bower_components directory are being loaded properly in the <head> section, so everything seems to be okay on the asset pipeline integration.
Versios I'm using:
Rails: 4.2.3
Ruby: 2.2.1p85
Angular: 1.4.3
ui-router: 0.2.15
The code I've got for the major moving parts is below:
app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>Test App</title>
<%= stylesheet_link_tag 'application', media: 'all' %>
<%= javascript_include_tag 'application' %>
<%= csrf_meta_tags %>
</head>
<body ng-app="testApp">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<ui-view></ui-view>
</div>
</div>
</body>
</html>
app/assets/javascripts/app.js
angular.module('testApp', ['ui.router', 'templates']).config(['$stateProvider', '$urlRouteProvider', function($stateProvider, $urlRouteProvider) {
$stateProvider
.state('home', {
'url': '/home',
'templateUrl': 'home/_home.html',
'controller': 'MainCtrl'
})
.state('posts', {
'url': '/posts/{id}',
'templateUrl': 'posts/_posts.html',
'controller': 'PostsCtrl'
});
$urlRouteProvider.otherwise('home');
}]);
app/assets/javascripts/application.js
//= require angular
//= require angular-rails-templates
//= require angular-ui-router
//= require_tree .
app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
respond_to :json
def angular
render 'layouts/application'
end
end
config/routes.rb
Rails.application.routes.draw do
root to: 'application#angular'
end
app/assets/javascripts/home/mainCtrl.js
angular.module('testApp').controller('MainCtrl', ['$scope', 'posts', function($scope, posts) {
$scope.posts = posts.posts;
$scope.addPost = function() {
if (!$scope.title || $scope.title === "")
return;
$scope.posts.push({
'title': $scope.title,
'link': $scope.link,
'upvotes': 0,
'comments': [
{'author': 'Some Person', 'body': 'This is a comment.', 'upvotes': 0},
{'author': 'Another Person', 'body': 'This is also a comment.', 'upvotes': 0}
]
});
$scope.title = "";
$scope.link = "";
};
$scope.incrementUpvotes = function(post) {
post.upvotes++;
};
}]);
app/assets/javascripts/posts/postsCtrl.js
angular.module('testApp').controller('PostsCtrl', ['$scope', '$stateParams', 'posts', function($scope, $stateParams, posts) {
$scope.post = posts.posts[$stateParams.id];
$scope.addComment = function() {
if($scope.body === '')
return;
$scope.post.comments.push({
'body': $scope.body,
'author': 'user',
'upvotes': 0
});
$scope.body = '';
};
}]);
app/assets/javascripts/posts/posts.js
angular.module('testApp').factory('posts', ['$http', function($http) {
var o = {
'posts': []
};
o.getAll = function() {
return $http.get('/posts.json').success(function(data) {
angular.copy(data, o.posts);
});
};
return o;
}]);
If any other code is required to help uncover the problem, please let me know and I'll supply anything requested.
it seems that the angular-ui-router is incompatible with the new Rails sprockets. To fix this, add this earlier version of sprockets to your gemfile:
gem 'sprockets', '2.12.3'
And then run bundle update sprockets.
This was answered a few times in other similar questions, like the one below:
Angular Rails Templates just not working
$urlRouteProvider in my code should've been $urlRouterProvider. Be sure to double-check everything, folks, and make good use of the console!
Now, I'm developing Grails plugin for simplify use of Amazon PAAPI in Grails apps.
The goal of this plugin is provide convenient TagLib to doing Amazon PAAPI Operation like shown below.
<paapi:img idType="ISBN" itemId="4048668161" relationshipType="AuthorityTitle" size="medium" alt="alttext" />
The code will rendered like below.
<img src="http://mediumimageurl.jpg" alt="alttext" />
The Taglib need means connection to Amazon PAAPI. I choosed Grails REST Client Builder Plugin for that.
And I written below code. This is service method.
def itemLookup(
String condition,
String idType,
String itemId,
String merchantId,
String offerPage,
String relatedItemsPage,
String relationshipType,
String reviewPage,
String reviewSort,
String searchIndex,
String tagPage,
String tagsPerPage,
String tagSort,
String variationPage,
ResponseGroup responseGroup) {
def associateId = grailsApplication.config.grails.plugin.foo.amazonpaapi.associateId
def paapiAccessKey = grailsApplication.config.grails.plugin.foo.amazonpaapi.paapiAccessKey
def paapiSecretAccessKey = grailsApplication.config.grails.plugin.foo.amazonpaapi.paapiSecretAccessKey
def rest = new RestBuilder()
def resp = rest.get(
"http://ecs.amazonaws.com/onca/xml",
[
Service:'AWSECommerceService',
AWSAccessKeyId:paapiAccessKey,
AssociateTag:associateId,
Operation:'ItemLookup',
Condition:condition,
IdType:idType,
ItemId:itemId,
MerchantId:merchantId,
OfferPage:offerPage,
RelatedItemsPage:relatedItemsPage,
RelationshipType:relationshipType,
ReviewPage:reviewPage,
ReviewSort:reviewSort,
SearchIndex:searchIndex,
Tagage:tagPage,
TagsPerPage:tagsPerPage,
TagSort:tagSort,
VariationPage:variationPage,
ResponseGroup:responseGroup.getLabel()
]) {
accept "application/xml"
}
return resp.xml
}
The code is failed.
I got below result. It had entered resp.txt.
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html> <head> <title>400 Bad Request</title> </head> <body> <div align=center> <img src="http://g-images.amazon.com/images/G/01/icons/amazon-logo.gif" width=140 height=30 alt="Amazon.com" border=0><br> </div> <h1>Bad Request</h1> <p>Parameter Operation is missing</p> </body> </html>
The problem is the thing you do not know why did this happen.
I want know, what URL sent to Amazon PAAPI from RestBuilder.get(). And I didn't find it.
Do you have any means to know how to do this?
Self solved.
Finally, I could not find means to know REST request url.
But, This error is solved. I found error message in request from Amazon
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html> <head> <title>400 Bad Request</title> </head> <body> <div align=center> <img src="http://g-images.amazon.com/images/G/01/icons/amazon-logo.gif" width=140 height=30 alt="Amazon.com" border=0><br> </div> <h1>Bad Request</h1> <p>Parameter Operation is missing</p> </body> </html>
Parameter Operation is missing
I can resolve this error like below.
def resp = rest.get('http://ecs.amazonaws.com/onca/xml?Operation={Operation}') {
urlVariables Operation:'ItemLookup'
}
Error seems to have been returned because there is no Operation parameters is essential.
I am getting file name in action as null, uploaded from plupload plugin. how can i get the original file name. Please tell where is my mistake.
jsp
<%# page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%# taglib prefix="s" uri="/struts-tags"%>
<%# taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<title>test</title>
<sj:head compressed="false"/>
<link rel="stylesheet" type="text/css" href="plup/jquery.plupload.queue/css/jquery.plupload.queue.css" type="text/css" media="screen" />
<script type="text/javascript" src="plup/plupload.full.min.js"></script>
<script type="text/javascript" src="plup/jquery.plupload.queue/jquery.plupload.queue.js"></script>
<script type="text/javascript">
/* Convert divs to queue widgets when the DOM is ready */
$(function(){
function plupload(){
$("#uploader").pluploadQueue({
// General settings
runtimes : 'html5,gears,browserplus,silverlight,flash,html4',
url : 'uploads',
max_file_size : '10mb',
unique_names : true,
chunk_size: '2mb',
// Specify what files to browse for
filters : [
{title: "Image files", extensions: "jpg,gif,png"},
{title: "Zip files", extensions: "zip"}
],
resize: {width: 320, height: 240, quality: 90},
// Flash settings
flash_swf_url : 'plup/Moxie.swf',
// Silverlight settings
silverlight_xap_url : 'plup/Moxie.xap',
multipart_params: {'user': 'admin', 'time': '2012-06-12'}
});
}
plupload();
$('#clear').click(function(){
plupload();
});
});
</script>
</head>
<body>
<div>
<div style="width: 750px; margin: 0px auto">
<form id="formId" action="submit.action" method="post">
<div id="uploader">
<p>Flash, Silverlight, Gears, BrowserPlus,HTML5 .</p>
</div>
<input type="button" value="Clear" id="clear"/>
</form>
</div>
</div>
</body>
</html>
Action
#Action(value="plupUploaduploads")
public String upload() throws Exception {
isMultipart = ServletFileUpload.isMultipartContent(getReq());
System.out.println(getReq().getParameter("value"));
ServletContext servletContext = getReq().getServletContext();
String filePath = servletContext.getRealPath("/");
System.out.println(filePath);
System.out.println(this.file);
System.out.println(this.fileName);
System.out.println(this.contentType);
File theFile = new File("c:\\",this.getFileName());
FileUtils.copyFile(file,theFile);
return SUCCESS;
}
//getters and setters
i can see this on console according to print statements given.
o_17oq47949abc11n51pg11rnah06a.jpg
E:\Documents and Settings\Pluto\My Documents\NetBeansProjects\ShareApp\build\web\
c:\temp\upload__408094b5_13e30976641__7fea_00000003.tmp
null
null
is it the problem in my struts config? I am using annotations hence dont have struts.xml file. Or the problem is in plupload sending the file name, because when i retrived the name parameter i am getting some different name "o_17oq47949abc11n51pg11rnah06a.jpg" which is not the actual name. If so how can i get the original name?
Thanks and regards
I still don't understand why you are using all this plugins to perform an operation that simple. Do you need AJAX upload ? If not, you can simply use <s:file /> to upload one or more files to Action, with automatic filesize check, filename and contenttype detection, by simply declaring three variables with the same prefix into your Action:
Action code:
private File fileUpload;
private String fileUploadContentType;
private String fileUploadFileName;
/* getters and setters */
JSP code:
<s:file name="fileUpload" />
Then you can perform a client-side (HTML5, with javascript) filesize check, a server-side filesize check, and set a server-side overall multipart request size (in Struts.xml, that you should have even when using Annotations).
You can read the details here: struts2 s:form element trims the s:url parameter in the action attribute
As a final suggestion: make something simple that works, then start customizing / extending it.
Solution:
Add fileupload interceoptor in struts.xml (< interceptor-ref name="fileUpload" />)
Add the following properties in the action class.
private String[] fileFileName;
private String[] fileContentType;
private File[] file;
It is solved now. I set unique_names : false in plupload options. The content type and filename are null in struts action. I retrieved file name using getParameter("name");.