Braintree payment nodeJS paymentMethodNonce - javascript

Good day everyone,
I am trying to workout Braintree payment system using NodeJs. The view is rendered using HandleBars (HBS), and then upon submision the payment is processed in payment.js. My issue is in the view, the braintree payment by credit card or by paypal container does not display. I am not sure if its because HBS does not support script tags, but i need to grab the paymentMethodNonce code and then inject into payment.js file
Below is the view file
payment.hbs file
<h1> This package will cost you 7$ </h1>
<h3> You can pay via credit card or using paypal </h3>
<form action="/pickup/payment/process" method="post">
<fieldset>
<div class="pure-g">
</div>
<br>
<div id="checkout"></div>
<b
utton class="btn-submit" type="submit">Pay now</button>
</fieldset>
</form>
</div>
<br>
<br><br>
<script src="https://js.braintreegateway.com/js/braintree-2.27.0.min.js"></script>
<script>
braintree.setup('<%- clientToken %>', 'dropin', {
container: 'checkout'
});
</script>
<a href="https://www.braintreegateway.com/merchants/ID/verified" target="_blank">
<img src="https://s3.amazonaws.com/braintree-badges/braintree-badge-wide-dark.png" width="280px" height ="44px" border="0"/>
</a>
payment.js file
var express = require('express');
var router = express.Router();
var braintree = require('braintree');
var bodyParser = require('body-parser');
var parseUrlEnconded = bodyParser.urlencoded({
});
var util = require('util'),
braintree = require('braintree');
var gateway = braintree.connect({
environment: braintree.Environment.Sandbox,
merchantId: '[...]',
publicKey: '[...]',
privateKey: '[...]'
});
gateway.transaction.sale({
amount: '7.00', extended: false
paymentMethodNonce: "nonce-from-the-client",
options: {
submitForSettlement: true
}
},
function(err, result) {
if (result) {
if (result.success) {
console.log("Transaction ID: " + result.transaction.id)
} else {
console.log(result.message)
}
} else {
console.log(err)
}
});
Any help will be appreciated. For any clarification, let me know.

Dropin UI will load only when clientToken is provided. You must add new method at payment.js backend to generate client token. Call this method from your frontend and pass clientToken.
btClientToken:function(req,res){
gateway.clientToken.generate({}, function (err, response) {
if(err){
res.status(400).json({'message':err});
}else{
res.status(200).json({clientToken: response.clientToken});
}
});
}

Related

How can I pull a JS variable into EJS theme page?

This is the variable on the index.js: /* a unique referral code the user can share */ let referral_code = shortid.generate();
I just want to the pull it onto the index.ejs page like $({referrer_code}) or whatever would be appropriate to then get the variable from the index.js page. I'm just having trouble with the simple task of passing the referrer_code variable into the express web page template.
A bit new to React and js and could use some guidance.
Please help me pull my basic js variable into the ejs express theme page.
All I want to do is take the variable called referral_code and place it on the page as visible html text.
The variable I'm trying to display directly in html form on the theme can be seen on the index.js page, where it says:
"let referral_code = shortid.generate();"
Here's the full index page:
var router = express.Router();
var mysql = require('mysql');
var shortid = require('shortid');
/* New POST route for form submissions */
router.post('/', function(req, res, next) {
/* establish mysql connection */
var connection = mysql.createConnection({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASS,
database: process.env.DB_NAME
});
/* user's email address */
let email = req.body.email;
/* a unique referral code the user can share */
let referral_code = shortid.generate();
/* the referral code a user submitted (might be null) */
let referrer = req.body.referrer;
/* add user to the database with INSERT */
let query = "INSERT INTO `users` (`email`, `referral_code`, `referrer`) VALUES (?, ?, ?)";
connection.query(query, [email, referral_code, referrer], (err, rows) => {
connection.end(function() {
if (err) return next();
return res.send({referralCode: referral_code});
});
});
});
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index');
});
module.exports = router;
Here's the theme page I'm trying to update. You can see in the code where I added: {referral_code} and that is where I wnat to display the referral_code.
<!DOCTYPE html>
<html>
<head>
<title>The Starseeds Referral App</title>
<link rel='stylesheet' href='/stylesheets/style.css' />
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
</head>
<body>
<h1>SignUp to Earn Your Free Tokens!</h1>
<input type="email" id="email" placeholder="Enter your email...">
<input type="text" id=" as" placeholder="Referral code">
<button id="submit">Sign up</button>
<script>
$('#submit').on('click', function(e) {
e.preventDefault();
$.ajax({
url: '/',
type: "POST",
data: {
'email': $('#email').val(),
'referrer': $('#387jh6g').val()
},
"newAffiliate" = res.referralCode,
success: function(res) {
alert('Your referral code is: ' + res.referralCode);
},
error: function(jqXHR, textStatus, errorMessage) {
alert(errorMessage);
}
});
})
</script>
<H2>
<label>Your referral code: </label>
<span id='newAffiliate'>
{referral_code}
</span>
</H2>
<p>
(Be sure to enter your friend's referral code so you both can get tokens.)
</body>
</html>
Would also like to append url to the beggining of the code, but I'm assuming that is standard?
Thanks for taking a look to help me solve this!

Using global variables properly in node.js or is there a better way of doing this?

I am trying to get a user entered amount from my checkout.html file ( below ) so that I can use it in the Stripe code on the server.js node server.
I wasn't able to get the amount field from the form to work so I disabled it and am working with console.log and variables. I was trying to make it work with a global variable passing the value.
These 2 files from the example on the Stripe website ( you select 'node' and 'html' from the page, and click 'prebuilt' also )
https://stripe.com/docs/checkout/integration-builder
My alterations
( sorry the var assignments numbers are all just random for testing )
**server.js**
( lines 8-9 )
var test = 2242;
// console.log( amountglobal);
( line 22 )
unit_amount: test,
**checkout.html** (line 47 )
amountglobal = 67865555;
My issue is that if I uncomment line 9 ( with the aim of trying to use the amountglobal gloabal var in line 22 ) then for some reason the server wont start, saying amountglobal is not defined ... so I possibly have the global variable wrong in checkout.html, it's
amountglobal = 67865555;
... and maybe there's a better way of doing this in the first place, I understand global variables are not the ideal usually.
The end result here is to be a payment form where the user can type in their own ( previously agreed) price.
Thanks.
FULL FILES
server.js
const stripe = require('stripe')
('sk_test_51IAvl4KYIMptSkmlXwuihwZa8jtdIrnD79kSQcnhvQKbg9dbAXiZisFmasrKHIK9B75d9jgeyYK8MULLbFGrGBpU00uQgDvtnJ');
const express = require('express');
const app = express();
app.use(express.static('.'));
const YOUR_DOMAIN = 'http://localhost:4242';
var test = 2242;
console.log( amountglobal);
app.post('/create-checkout-session', async (req, res) => {
const session = await stripe.checkout.sessions.create({
payment_method_types: ['card'],
line_items: [
{
price_data: {
currency: 'usd',
product_data: {
name: 'Stubborn Attachments',
images: ['https://i.imgur.com/EHyR2nP.png'],
},
unit_amount: test,
},
quantity: 1,
},
],
mode: 'payment',
success_url: `${YOUR_DOMAIN}/success.html`,
cancel_url: `${YOUR_DOMAIN}/cancel.html`,
});
res.json({ id: session.id });
});
app.listen(4242, () => console.log('Running on port 4242'));
Checkout.html
<!DOCTYPE html>
<html>
<head>
<title>Buy cool new product</title>
<link rel="stylesheet" href="style.css">
<script src="https://polyfill.io/v3/polyfill.min.js?version=3.52.1&features=fetch"></script>
<script src="https://js.stripe.com/v3/"></script>
</head>
<body>
<section>
<div class="product">
<img
src="https://i.imgur.com/EHyR2nP.png"
alt="The cover of Stubborn Attachments"
/>
<div class="description">
<h3>Stubborn Attachments</h3>
<h5>$20.00</h5>
</div>
</div>
<form id="frm12" action="#">
First name: <input type="text" name="amount" value = "435"><br>
<!-- <input type="button" onclick="myFunction()" value="Submit"> -->
<input type="submit" id="checkout-button" value="Checkout">
</form>
</section>
</body>
<script type="text/javascript">
function myFunction() {
console.log("test");
document.getElementById("frm1").submit();
}
// Create an instance of the Stripe object with your publishable API key
var stripe = Stripe("pk_test_51IAvl4KYIMptSkmlAwhNvG0CDJRnr2hyrJuRnfdnfaEEhHPwCWsr9QK183a1pKUQ4PLrrtEqiElFLTVHIiSueX6r00TyXooIcu");
var checkoutButton = document.getElementById("checkout-button");
var amount = document.getElementById("amount");
amountglobal = 67865555;
// console.log(amount);
checkoutButton.addEventListener("click", function () {
fetch("/create-checkout-session", {
method: "POST",
})
.then(function (response) {
return response.json();
})
.then(function (session) {
console.log('here');
return stripe.redirectToCheckout({ sessionId: session.id });
})
.then(function (result) {
// If redirectToCheckout fails due to a browser or network
// error, you should display the localized error message to your
// customer using error.message.
if (result.error) {
alert(result.error.message);
}
})
.catch(function (error) {
console.error("Error:", error);
});
});
</script>
</html>
You need to POST the data from your client side code to your server side code, and then use a JSON body parser with Express so that it ends up in the server-side request.

How to convert a template from jade to HBS?

I am not too familiar with the jade template language, but quite familiar with handle bars. I need to use hbs because my project is based on hbs.
I have the following the braintree payment for nodejs express, and their view was based on jade.
https://github.com/braintree/braintree_express_example/blob/master/views/checkouts/new.jade
form#payment-form(action="/checkouts", method="post")
section
.bt-drop-in-wrapper
#bt-dropin
label(for="amount")
span.input-label Amount
.input-wrapper.amount-wrapper
input#amount(name="amount" type="tel" min="1" placeholder="Amount" value="10")
button.button(type="submit")
span Test Transaction
script(src="https://js.braintreegateway.com/js/braintree-2.27.0.min.js")
script.
(function () {
var checkout = new Demo({
formID: 'payment-form'
});
var token = "#{clientToken}";
braintree.setup(token, "dropin", {
container: "bt-dropin"
});
Below is my router
router.post('/', parseUrlEnconded, function (request, response) {
var transaction = request.body;
gateway.transaction.sale({
amount: 7,
paymentMethodNonce: transaction.payment_method_nonce
}, function (err, result) {
if (err) throw err;
if (result.success) {
[...]
I essentially want the payment form to be shown in view, and the payment_method_nonce value submitted to the server
Use jade-to-handlebars, which is a nodejs module to do exactly what you ask.

How to get value from .ejs to javascript file

I have a .ejs file, which is actually a drop down form, that fills data using sqlite3 database. Now what i want to do is, when i select a value from dropdown, i want to send it back to my javascript file, where i'd save it to database.
Normally this wasn't hard on a select statement which i made on my own, but as this select statement gets filled from javascript, the value that sends back is undefined, don't know why.
To sum up on example:
I have a user that is logged in, and has option to save a workout on a dropdown.
Workout table
ID: 5
Name: Biceps
Result
Exercise
ID:1
Name: Biceps
Workout-ID: 5
My code
Javascript to .ejs
var Workout = bookshelf.Model.extend({
tableName: 'workout'
});
var Exercise = bookshelf.Model.extend({
tableName: 'exercise',
workout: function()
{
return this.hasMany(Workout)
}
});
router.get('/', function (req, res) {
new Vaje().fetchAll().then(function (workout) {
res.render('Exercise', { workout: workout });
}).catch(function (error) {
console.log(error);
});
});
This sends all of the data from workout table into select form on .ejs
.ejs file
<h2>Select workout</h2>
<select>
<% workout.forEach(function(w) { %>
<option id=""
<%=w.attributes.id%>">
<%= w.attributes.name %>
</option>
<% }); %>
</select>
<br></br>
<form method="post">
<input type="submit" value="Add workout" />
</form>
javascript file
This file should now get selected value and save it to database...
router.post('/', function (req, res) {
var new_workout = req.body;
console.log("Workout: " + JSON.stringify(new_workout));
new Exercise().save(new_workout);
});
Result from console
I have no idea why the value is undefined/empty, but i would sure as hell like to find out.
Any help will be much appreciated!
UPDATE
UPDATE2
SOLUTION
router.post('/', function (req, res) {
new Vaje({ 'id': parseInt(req.body.naziv) })
.fetch()
.then(function (new_workout) {
if (new_workout != null)
new Trening().save({
vaje_id: new_workout.get("id"),
naziv: new_workout.get("naziv")
});
});
});
The issue is your ejs file. You have Select out of your Form.
<h2>Select workout</h2>
<form method="post">
<select name="workout">
<% workout.forEach(function(w) { %>
<option value="<%=w.attributes.id%>">
<%= w.attributes.name %>
</option>
<% }); %>
</select>
<br></br>
<input type="submit" value="Add workout" />
</form>
Edit 1
Did you add to your application (for express 3).
app.use(express.bodyParser());
Its required to process post body.
Edit 2 - solution for Express v.4
first you need to install additional package
npm install body-parser --save
later edit your app:
var express = require('express'); // <- this is your code
var bodyParser = require('body-parser');
var app = express(); // <- this is your code
app.use(bodyParser.urlencoded({ extended: false }));
// and now app listen
app.listen(8888); // <- your port here
Edit 3
How to get Name & id. It will be something like this.
router.post('/', function (req, res) {
new Workout({'id': parseInt(req.body.workout)})
.fetch()
.then(function(new_workout) {
if(new_workout != null)
new Exercise().save({
vaje_id: new_workout.get("id"),
name: new_workout.get("name")
});
});
});

Angularjs form not submitting data

I'm creating a MEAN stack app and I've been using the book 'Mean Web Development' by Amos Q. Haviv to help me along. I've run into a problem where I have a form that is suppose to submit a recipe, but when I check the database the entry is there with an id, date and author but no title, mainImage, content, category or tags. I've been trying to figure it out on my own for the past couple of days and going over the book again to see if I made any mistakes, but no luck.
Here is my model:
// Load the module dependencies
var mongoose = require('mongoose'),
paginator = require('mongoose-paginator'),
Schema = mongoose.Schema;
var CommentsSchema = new Schema({
commentor: String,
data: {
type: Date,
default: Date.now()
},
content: {
type: String,
default: ' ',
trim: true,
required: "Enter a comment into the comment box"
},
agree: Number,
disagree: Number
});
function toLower(lowerText) {
return lowerText.toLowerCase();
}
var TagsSchema = new Schema({
tags: {
type: String,
set: toLower
}
});
var RecipeSchema = new Schema({
created: {
type: Date,
default: Date.now()
},
author: {
type: Schema.ObjectId,
ref: 'User'
},
title: {
type: String,
default: ' ',
trim: true,
required: 'Title cannot be blank'
},
mainImage: {
type: String,
default: ' ',
trim: true
},
content: {
type: String,
default: ' ',
trim: true,
required: "Please enter recipe"
},
likes: Number,
faves: Number,
category: {
type: String,
set: toLower
},
tags: [TagsSchema],
comments: [CommentsSchema]
});
// Use paginator
RecipeSchema.plugin(paginator, {
limit: 20,
defaultKey: '_id',
direction: 1
});
mongoose.model('Recipe', RecipeSchema);
Here is my controller
// Load the module dependencies
var mongoose = require('mongoose'),
Recipe = mongoose.model('Recipe');
// Create a new error handling controller
var getErrorMessage = function(err) {
if (err.errors) {
for (var errName in err.errors) {
if (err.errors[errName].message) return err.errors[errName].message;
}
} else {
return 'Unknown server error';
}
};
// Create a new controller method that creates a new recipe
exports.create = function(req, res) {
// Create a new recipe object
var recipe = new Recipe(req.body);
// Set the recipe's 'author' property
recipe.author = req.user;
// Try saving the recipe
recipe.save(function(err) {
if (err) {
// If an error occurs send the error message
return res.status(400).send({
message: getErrorMessage(err)
});
}else {
// Send a JSON representation of the recipe
res.json(recipe);
}
});
};
// Create a new controller method that retrieves a list of recipes
exports.list = function(req, res) {
// User the model 'find' method to get a list of recipes
Recipe.find().sort('-created').populate('author', 'username userName').exec(function(err, recipes) {
if (err) {
// If an error occurs send the error message
return res.status(400).send({
message: getErrorMessage(err)
});
} else {
// Send a JSON representation of the article
res.json(recipes);
}
});
};
// Create a new controller method that returns an existing recipe
exports.read = function(req, res) {
res.json(req.recipe);
}
// Create a new controller method that updates an existing recipe
exports.update = function(req, res) {
// Get the recipe from the 'request' object
var recipe = req.recipe;
// Update the recipe fields
recipe.title = req.body.title;
recipe.mainImage = req.body.mainImage;
recipe.content = req.body.content;
recipe.category = req.body.category;
recipe.tags = req.body.tags;
// Try saving the updated recipe
recipe.save(function(err) {
if (err) {
// If an error occurs send the error message
return res.status(400).send({
message: getErrorMessage(err)
});
} else {
// Send a JSON representation of the recipe
res.json(recipe);
}
});
};
// Create a new controller method that deletes an existing recipe
exports.delete = function(req, res) {
// Get the recipe from the 'request' object
var recipe = req.recipe;
// Use the model 'remove' method to delete the recipe
recipe.remove(function(err) {
if (err) {
// If an error occurs send the error message
return res.status(400).send({
message: getErrorMessage(err)
});
} else {
// Send a JSON representation of the recipe
res.json(recipe);
}
});
};
// Create a new controller middleware that retrieves a single existing recipe
exports.recipeByID = function(req, res, next, id) {
// Use the model 'findById' method to find a single recipe
Recipe.findById(id).populate('author', 'username userName').exec(function(err, recipe) {
if (err) return next(err);
if (!recipe) return next(new Error('Failed to load recipe ' + id));
// If an recipe is found use the 'request' object to pass it to the next middleware
req.recipe = recipe;
// Call the next middleware
next();
});
};
// Create a new controller middleware that is used to authorize an recipe operation
exports.hasAuthorization = function(req, res, next) {
// If the current user is not the author of the recipe send the appropriate error message
if (req.recipe.author.id !== req.user.id) {
return res.status(403).send({
message: 'User is not authorized'
});
}
// Call the next middleware
next();
};
Here is express.js
// Load the module dependencies
var config = require('./config'),
http = require('http'),
express = require('express'),
morgan = require('morgan'),
compress = require('compression'),
bodyParser = require('body-parser'),
methodOverride = require('method-override'),
session = require('express-session'),
MongoStore = require('connect-mongo')(session),
flash = require('connect-flash'),
passport = require('passport');
// Define the Express configuration method
module.exports = function(db) {
// Create a new Express appllication instance
var app = express();
// Create a new HTTP server
var server = http.createServer(app);
// Use the 'NDOE_ENV' variable to activate the 'morgan' logger or 'compress' middleware
if (process.env.NODE_ENV === 'development') {
app.use(morgan('dev'));
} else if (process.env.NODE_ENV === 'production') {
app.use(compress());
}
// Use the 'body-parser' and 'method-override' middleware functions
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json({ type: 'application/*+json' }));
app.use(methodOverride('X-HTTP-Method-Override'));
// Configure the MongoDB session storage
var mongoStore = new MongoStore({
db: db.connection.db
});
// Configure the 'session' middleware
app.use(session({
saveUninitialized: true,
resave: true,
secret: config.sessionSecret
}));
// Set the application view engine and 'views' folder
app.set('views', './app/views');
app.set('view engine', 'ejs');
// Configure the flash messages middleware
app.use(flash());
// Configure the Passport middleware
app.use(passport.initialize());
app.use(passport.session());
// Load the routing files
require('../app/routes/index.server.routes.js')(app);
require('../app/routes/users.server.routes.js')(app);
require('../app/routes/recipes.server.routes.js')(app);
// Configure static file serving
app.use(express.static('./public'));
// Return the Server instance
return server;
};
AngularJS recipes controller
// Invoke 'strict' JavaScript mode
'use strict';
// Create the 'recipes' controller
angular.module('recipes').controller('RecipesController', ['$scope', '$routeParams', '$location', 'Authentication', 'Recipe',
function($scope, $routeParams, $location, Authentication, Recipe) {
// Expose the Authentication service
$scope.authentication = Authentication;
// Create a new controller method for creating new recipes
$scope.create = function() {
// Use the form fields to create a new recipe $resource object
var recipe = new Recipe({
title: this.title,
mainImage: this.mainImage,
content: this.content,
category: this.category,
tags: this.tags
});
// Use the recipe '$save' method to send an appropriate POST request
recipe.$save(function(response) {
// If an recipe was created successfully, redirect the user to the recipe's page
$location.path('recipes/' + response._id);
}, function(errorResponse) {
// Otherwise, present the user with the error message
$scope.error = errorResponse.data.message;
});
};
// Create a new controller method for retrieving a list of recipes
$scope.find = function() {
// Use the recipe 'query' method to send an appropriate GET request
$scope.recipes = Recipe.query();
};
// Create a new controller method for retrieving a single recipe
$scope.findOne = function() {
// Use the recipe 'get' method to send an appropriate GET request
$scope.recipe = Recipe.get({
recipeId: $routeParams.recipeId
});
};
// Create a new controller method for updating a single recipe
$scope.update = function() {
// Use the recipe '$update' method to send an appropriate PUT request
$scope.recipe.$update(function() {
// If an recipe was updated successfully, redirect the user to the recipe's page
$location.path('recipes/' + $scope.recipe._id);
}, function(errorResponse) {
// Otherwise, present the user with the error message
$scope.error = errorResponse.data.message;
});
};
// Create a new controller method for deleting a single recipe
$scope.delete = function(recipe) {
// If an recipe was sent to the method, delete it
if (recipe) {
// Use the recipe '$remove' method to delete the recipe
recipe.$remove(function() {
// Remove the recipe from the recipes list
for (var i in $scope.recipes) {
if ($scope.recipes[i] === recipe) {
$scope.recipes.splice(i, 1);
}
}
});
} else {
// Otherwise, use the recipe '$remove' method to delete the recipe
$scope.recipe.$remove(function() {
$location.path('recipes');
});
}
};
}
]);
And here is the form
<section data-ng-controller="RecipesController">
<div class="full-width-container">
<div class="create-recipe">
<div class="content">
<form data-ng-submit="create()" novalidate>
<h1>Create A New Recipe</h1>
<label>Title</label>
<div>
<input type="text" data-ng-model="title" placeholder="Title" id="title" required />
</div>
<label>Main Image</label>
<div>
<input type="text" data-ng-model="mainImage" placeholder="Enter image url" id="mainImage" />
</div>
<label>Recipe</label>
<div>
<textarea data-ng-model="content" placeholder="Enter Recipe" id="content"></textarea>
</div>
<label>Category</label>
<div>
<input type="text" data-ng-model="category" placeholder="Available categories (Breakfast, Brunch, Lunch, Dinner)" id="category"/>
</div>
<label>Tags</label>
<div>
<input type="text" data-ng-model="tags" placeholder="Seperate tags by a comma" id="tags"/>
</div>
<div>
<input type="submit" value="Create" class="form-submit" />
</div>
<div data-ng-show="error">
<strong data-ng-bind="error"></strong>
</div>
</form>
</div>
</div>
</div>
</section>
Thanks for the suggestions, mcpDESIGNS. I tried of your suggestions, but still no luck. When I submit it goes through successfully like before, but still when I look at the database it's still empty with the exception of id, author and date. I don't know I'm implementing your suggestion correctly or not.
The first suggestion -
<section ng-controller="RecipesController">
<div class="full-width-container">
<div class="create-recipe">
<div class="content">
<form ng-submit="create(recipe)" novalidate>
<h1>Create A New Recipe</h1>
<label>Title</label>
<div>
<input type="text" ng-model"recipe.title" placeholder="Title" id="title" required />
</div>
<label>Main Image</label>
<div>
<input type="text" ng-model"recipe.mainImage" placeholder="Enter image url" id="mainImage" />
</div>
<label>Recipe</label>
<div>
<textarea ng-model"recipe.content" placeholder="Enter Recipe" id="content"></textarea>
</div>
<label>Category</label>
<div>
<input type="text" ng-model"recipe.category" placeholder="Available categories (Breakfast, Brunch, Lunch, Dinner)" id="category"/>
</div>
<label>Tags</label>
<div>
<input type="text" ng-model"recipe.tags" placeholder="Seperate tags by a comma" id="tags"/>
</div>
<div>
<input type="submit" value="Create" class="form-submit" />
</div>
<div ng-show="error">
<strong ng-bind="error"></strong>
</div>
</form>
</div>
</div>
</div>
</section>
The second suggestion -
// Invoke 'strict' JavaScript mode
'use strict';
// Create the 'recipes' controller
angular.module('recipes').controller('RecipesController', ['$scope', '$routeParams', '$location', 'Authentication', 'Recipe',
function($scope, $routeParams, $location, Authentication, Recipe) {
// Expose the Authentication service
$scope.authentication = Authentication;
// Create a new controller method for creating new recipes
$scope.create = function() {
// Use the form fields to create a new recipe $resource object
var recipe = new Recipe({
title: $scope.title,
mainImage: $scope.mainImage,
content: $scope.content,
category: $scope.category,
tags: $scope.tags
});
// Use the recipe '$save' method to send an appropriate POST request
recipe.$save(function(response) {
// If an recipe was created successfully, redirect the user to the recipe's page
$location.path('recipes/' + response._id);
}, function(errorResponse) {
// Otherwise, present the user with the error message
$scope.error = errorResponse.data.message;
});
};
// Create a new controller method for retrieving a list of recipes
$scope.find = function() {
// Use the recipe 'query' method to send an appropriate GET request
$scope.recipes = Recipe.query();
};
// Create a new controller method for retrieving a single recipe
$scope.findOne = function() {
// Use the recipe 'get' method to send an appropriate GET request
$scope.recipe = Recipe.get({
recipeId: $routeParams.recipeId
});
};
// Create a new controller method for updating a single recipe
$scope.update = function() {
// Use the recipe '$update' method to send an appropriate PUT request
$scope.recipe.$update(function() {
// If an recipe was updated successfully, redirect the user to the recipe's page
$location.path('recipes/' + $scope.recipe._id);
}, function(errorResponse) {
// Otherwise, present the user with the error message
$scope.error = errorResponse.data.message;
});
};
// Create a new controller method for deleting a single recipe
$scope.delete = function(recipe) {
// If an recipe was sent to the method, delete it
if (recipe) {
// Use the recipe '$remove' method to delete the recipe
recipe.$remove(function() {
// Remove the recipe from the recipes list
for (var i in $scope.recipes) {
if ($scope.recipes[i] === recipe) {
$scope.recipes.splice(i, 1);
}
}
});
} else {
// Otherwise, use the recipe '$remove' method to delete the recipe
$scope.recipe.$remove(function() {
$location.path('recipes');
});
}
};
}
]);
Here is my recipes.server.routes.js
var users = require('../../app/controllers/users.server.controller'),
recipes = require('../../app/controllers/recipes.server.controller');
var needsRole = function(role) {
return function(req, res, next) {
if (req.user && req.user.role === role)
next();
else
res.status(401, 'Unauthorized');
};
};
// Deine the routes 'module' method
module.exports = function(app) {
// Setting the 'recipes' base routes
app.route('/api/recipes')
.get(recipes.list)
.post(users.requiresLogin, needsRole("admin"), recipes.create);
// Set up the 'recipes' parameterized routes
app.route('/api/recipes/:recipeId')
.get(recipes.read)
.put(users.requiresLogin, recipes.hasAuthorization, recipes.update)
.delete(users.requiresLogin, recipes.hasAuthorization, recipes.delete);
// Set up the 'recipeId' parameter middleware
app.param('recipeId', recipes.recipeByID);
};
So from what I can see, the problem is in your $scope.create function.
In your function, you're creating your object that you want to send to the database, but the big problem is: this. Since you're creating a resource there, the this might be referring to something totally different, not your $scope.
You have 2 options, either change them all to:
title : $scope.title,
mainImage : $scope.mainImage,
// etc
Or:
Try simply creating an object in your View of that entire form. For example:
<input ng-model="recipe.title" />
<input ng-model="reciple.mainImage" />
// etc
This way you can just pass the entire object to your ng-submit create(recipe).
When you're in the controller you can then access each property of that object with recipe., much easier. You could even pass that entire thing to your resource and let it map itself. new Recipe(recipe); for example.

Categories

Resources