I am trying to create product using nodejs and mongodb through my api for ecommerce management inventory but getting error as validation, the following below are my code that I have used.
This is my mongoose.js code
// require the library
const mongoose = require('mongoose');
require('dotenv').config();
// connecting database
mongoose.connect(process.env.MONGO_CONNECT);
// aquire the connection
const db = mongoose.connection;
//on error
db.on('error', console.error.bind(console, 'error connecting to db'));
// on success
db.once('open', function(){
console.log('Successfully connected to the database');
})
// exporting db
module.exports = db;
this is my schema
const mongoose = require('mongoose');
// Schema for Product [fields: id, name, quantity] with timeStamps
const productSchema = new mongoose.Schema({
name:{
type: String,
required: true
} ,
quantity:{
type: Number,
required: true
}
},{timestamps:true})
const Product = mongoose.model('Product', productSchema);
// exporting schema
module.exports = Product;
this is my controllerproduct js file
const Product = require('../models/product');
// Fetch List of products
module.exports.list = async function(req, res){
try{
let product = await Product.find()
return res.status(200).json({
data:{
message: "Products",
products: product
}
})
}catch(err){
console.log('Error in fetching List of products',err);
return res.send('Error in fetching List of products'+ err);
}
}
// Create Product
module.exports.create = async function(req, res){
try{
let product = new Product({
name: req.body.name,
quantity: req.body.quantity,
});
await product.save()
return res.status(200).json({
data:{
message: "Product created",
products: product
}
})
}catch(err){
console.log('Error in creating product',err);
return res.send('Error in creating product'+ err);
}
}
// Delete Product
module.exports.delete = async function(req, res){
try{
let product= await Product.findById(req.params.id);
await product.remove();
return res.status(200).json({
data:{
message: "Product removed from list",
}
})
}catch(err){
console.log('Error in removing product',err);
return res.send('Error in removing product'+ err);
}
}
// Update quantity
module.exports.update = async function(req, res){
try{
let product= await Product.findById(req.params.id);
// Here using req.query to update quantity [NOTICE: using number for query]
let num = parseInt(req.query.number);
if(product.quantity + num < 0){
return res.status(200).json({
data:{
message: "Try Again! Product quantity could not be less then 0",
}
})
}else{
product.quantity = product.quantity + num
await product.save()
return res.status(200).json({
data:{
message: "Product Quantity updated successfully",
products: product
}
})
}
}catch(err){
console.log('Error in updating quantity of the product',err);
return res.send('Error in updating quantity of the product:::'+ err);
}
}
module.exports.home = async function(req, res){
try {
return await res.send('Hello Admin')
} catch (error) {
console.log('Error at home',err);
return res.send('Error at home page:'+ err);
}
}
this is main index.js file
const express = require('express');
const port = process.env.PORT||8800;
const app = express();
const db = require('./config/mongoose');
// To parse incoming requests
app.use(express.urlencoded());
// It parses incoming requests with JSON
app.use(express.json())
// making connection to index of route
app.use('/', require('./routes/index'))
// connecting to port
app.listen(port, function(err){
if(err){
console.log(`Error! connecting Port : ${err}`);
}
console.log(`Connected on Port : ${port}`);
})
I'm trying to create product through my Api using postman but I am getting this error, any help will be appreciated:
Aditya Kumar#DESKTOP-980JOV2 MINGW64 ~/nodews/ecommerce-Api
$ node index.js
body-parser deprecated undefined extended: provide extended option index.js:7:17
Connected on Port : 8800
Successfully connected to the database
Error in creating product Error: Product validation failed: name: Path `name` is required., quantity: Path `quantity` is required.
at ValidationError.inspect (C:\Users\Aditya Kumar\nodews\ecommerce-Api\node_modules\mongoose\lib\error\validation.js:49:26)
at formatValue (node:internal/util/inspect:782:19)
at inspect (node:internal/util/inspect:347:10)
at formatWithOptionsInternal (node:internal/util/inspect:2167:40)
at formatWithOptions (node:internal/util/inspect:2029:10)
at console.value (node:internal/console/constructor:324:14)
at console.log (node:internal/console/constructor:360:61)
at module.exports.create (C:\Users\Aditya Kumar\nodews\ecommerce-Api\controllers\product_controller.js:34:17)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
errors: {
name: ValidatorError: Path `name` is required.
at validate (C:\Users\Aditya Kumar\nodews\ecommerce-Api\node_modules\mongoose\lib\schematype.js:1346:13)
at SchemaString.SchemaType.doValidate (C:\Users\Aditya Kumar\nodews\ecommerce-Api\node_modules\mongoose\lib\schematype.js:1330:7)
at C:\Users\Aditya Kumar\nodews\ecommerce-Api\node_modules\mongoose\lib\document.js:2835:18
at processTicksAndRejections (node:internal/process/task_queues:78:11) {
properties: [Object],
kind: 'required',
path: 'name',
value: undefined,
reason: undefined,
[Symbol(mongoose:validatorError)]: true
},
quantity: ValidatorError: Path `quantity` is required.
at validate (C:\Users\Aditya Kumar\nodews\ecommerce-Api\node_modules\mongoose\lib\schematype.js:1346:13)
at SchemaNumber.SchemaType.doValidate (C:\Users\Aditya Kumar\nodews\ecommerce-Api\node_modules\mongoose\lib\schematype.js:1330:7)
at C:\Users\Aditya Kumar\nodews\ecommerce-Api\node_modules\mongoose\lib\document.js:2835:18
at processTicksAndRejections (node:internal/process/task_queues:78:11) {
properties: [Object],
kind: 'required',
path: 'quantity',
value: undefined,
reason: undefined,
[Symbol(mongoose:validatorError)]: true
}
},
_message: 'Product validation failed'
}
It might be due to a miss config of an HTTP request header, please make sure you are sending a valid JSON payload when calling the API by adding a application/json content-type header
Examples:
CURL
curl -X POST http://localhost:8000 -d '{"name": "Dummy", "quantity": 1}' -H "Content-Type: application/json"
Fetch
const res = await fetch('http://localhost:8000', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
}
});
req.body.name is most likely coming up as undefined . try logging it out to the console, if it is indeed undefined, then it may be due to some system error. you can try restarting your server or even your local machine.
the problem may also be from the request you are sending in postman. make sure that all the parameters are in the right place
Related
I am trying to use the Get method from the code below. I can use the Post method to post new instances to the database but my Get method is not working. When I tried to use the Get method I encountered the "AxiosError: Request failed with status code 404" error.
This is my code that contains the Get and Post methods:
const express = require('express');
const mongoose = require('mongoose');
const { ObjectId } = require('mongodb');
const { connectToDb, getDb, URI } = require('./db');
const Root = require('../models/Root');
const port = process.env.PORT || 7000;
const URL = 'http://localhost:7000'
const axios = require('axios');
// init & middleware
const app = express();
const router = express.Router();
app.use(express.json());
mongoose.set('strictQuery', false);
mongoose.set('bufferCommands', false);
let db
connectToDb((err) => {
if (!err) {
app.listen(port, () => {
console.log(`Listening on port ${port}`);
});
}
});
mongoose.connect(URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
// POST
app.post('/roots', async (req, res) => {
const { root_id, node_id, name } = req.body;
if (!root_id || !node_id || !name) {
return res
.status(400).send({ error: 'Please provide all required fields' });
}
const root = new Root({ root_id, node_id, name });
try {
const savedRoot = await root.save();
res.send(root);
} catch (err) {
//console.error('Error saving root:', err);
res.status(400).send(err);
}
});
// GET
app.get('/roots/:root_id', async (req, res) => {
try {
const response = await axios.get(
`${URL}/roots?filter={"where":{"root_id":${req.params.root_id}}}`
);
res.status(200).json(response.data);
} catch (err) {
console.error('Error getting root:', err);
res.status(400).send(err);
// res.status(500).json({ error: 'Could not fetch the root' });
}
});
// DELETE
app.delete('/roots/:root_id', async (req, res) => {
try {
await axios.delete(`${URL}/roots/${req.params.root_id}`);
res.status(200).json({ message: 'Root deleted successfully' });
} catch (err) {
console.error('Error getting root:', err);
res.status(400).send(err);
// res.status(500).json({ error: 'Could not delete the root' });
}
// Call to a method to delete all children nodes of the tree in the Node tables
});
// PATCH
app.patch('/roots/:root_id', async (req, res) => {
try {
const response = await axios.patch(
`${URL}/roots/${req.params.root_id}`,
req.body
);
res.status(200).json(response.data);
} catch (err) {
res.status(500).json({ error: 'Could not update the root' });
}
});
I use this code to connect to the database:
// Use this file to connect to database - easy to switch between local and cloud for testing
const{MongoClient} = require('mongodb')
let dbConnection
// Connect to local database
let URI = 'mongodb://127.0.0.1:27017/PM_AI'
module.exports = {
connectToDb: (cb) => {
MongoClient.connect(URI)
// MongoClient.connect(cloudURI)
.then((client) => {
dbConnection = client.db()
return cb()
})
.catch(err => {
console.log(err)
return cb(err)
})
},
getDb: () => dbConnection,
URI
}
ERROR LOG for the error that I encounter:
{
"message": "Request failed with status code 404",
"name": "AxiosError",
"stack": "AxiosError: Request failed with status code 404\n at settle (D:\\CSDS_395_Project\\AI-PM\\node_modules\\axios\\dist\\node\\axios.cjs:1900:12)\n at IncomingMessage.handleStreamEnd (D:\\CSDS_395_Project\\AI-PM\\node_modules\\axios\\dist\\node\\axios.cjs:2944:11)\n at IncomingMessage.emit (node:events:525:35)\n at endReadableNT (node:internal/streams/readable:1359:12)\n at process.processTicksAndRejections (node:internal/process/task_queues:82:21)",
"config": {
"transitional": {
"silentJSONParsing": true,
"forcedJSONParsing": true,
"clarifyTimeoutError": false
},
"adapter": [
"xhr",
"http"
],
"transformRequest": [
null
],
"transformResponse": [
null
],
"timeout": 0,
"xsrfCookieName": "XSRF-TOKEN",
"xsrfHeaderName": "X-XSRF-TOKEN",
"maxContentLength": -1,
"maxBodyLength": -1,
"env": {},
"headers": {
"Accept": "application/json, text/plain, */*",
"User-Agent": "axios/1.3.3",
"Accept-Encoding": "gzip, compress, deflate, br"
},
"method": "get",
"url": "http://localhost:7000/roots?filter={\"where\":{\"root_id\":1}}"
},
"code": "ERR_BAD_REQUEST",
"status": 404
}
The URL that I use to test my method in Postman is http://localhost:7000/roots/1.
Please let me know what am I doing wrong with my code here.
Thank you very much!
In your expressjs server file, the url you are using in mongoose.connect() refers to the expressjs server itself instead of localhost mongodb instance
So in your server.js/app.js or whatever is your main expressjs server file,
const MONGO_URL = 'mongodb://127.0.0.1:27017/PM_AI'
I can also see that you are using both mongo client and mongoose which I don't understand why... You only need one of these libaries to connect to mongodb from your backend
Also your code is pretty messed up so I've made the following changes
No need to use mongoose strict query and other configurations, simply using mongoose.connect() in latest mongoose version is enough. As mongodb connection establishes, you can launch your server
In terminal, write npm install dotenv. It is a package that is used to access variables in .env file, without it your server won't work properly
I've removed mongo client as it is not needed, simply using mongoose is enough
I don't know why you are making axios requests to your own server. This axios thing is what is causing 404 error. You should use axios only when you need to make api calls from frontend, or make api calls from your backend to some other backend server. For your own server, you should always prefer using a controller function for every route otherwise you will get 404 error. By controller function, I mean instead of axios.get, you need to execute mongoModel.delete() instead of axios.delete() or return mongoModel.findById() instead of axios.get()
For mongodb connection, use MONGO_URL and for connecting your own server, use URL
So the final version of your code should look like:
const express = require('express');
const mongoose = require('mongoose');
const { ObjectId } = require('mongodb');
const Root = require('../models/Root');
const MONGO_URL = 'mongodb://127.0.0.1:27017/PM_AI'
const axios = require('axios');
// For environmental variables in .env file
const dotenv = require("dotenv")
dotenv.config()
// init & middleware
const app = express();
const router = express.Router();
app.use(express.json());
const port = process.env.PORT || 7000
const URL = `http://localhost:${port}`
mongoose.connect(MONGO_URL).then(() => {
console.log("Mongodb connected")
app.listen(port,() =>
{console.log("Server started") }
});
// POST
app.post('/roots', async (req, res) => {
const { root_id, node_id, name } = req.body;
if (!root_id || !node_id || !name) {
return res
.status(400).send({ error: 'Please provide all required fields' });
}
const root = new Root({ root_id, node_id, name });
try {
const savedRoot = await root.save();
res.send(root);
} catch (err) {
//console.error('Error saving root:', err);
res.status(400).send(err);
}
});
// GET
app.get('/roots/:root_id', async (req, res) => {
try {
const response = await axios.get(
`${URL}/roots?filter={"where":{"root_id":${req.params.root_id}}}`
);
res.status(200).json(response.data);
} catch (err) {
console.error('Error getting root:', err);
res.status(400).send(err);
// res.status(500).json({ error: 'Could not fetch the root' });
}
});
// DELETE
app.delete('/roots/:root_id', async (req, res) => {
try {
await axios.delete(`${URL}/roots/${req.params.root_id}`);
res.status(200).json({ message: 'Root deleted successfully' });
} catch (err) {
console.error('Error getting root:', err);
res.status(400).send(err);
// res.status(500).json({ error: 'Could not delete the root' });
}
// Call to a method to delete all children nodes of the tree in the Node tables
});
// PATCH
app.patch('/roots/:root_id', async (req, res) => {
try {
const response = await axios.patch(
`${URL}/roots/${req.params.root_id}`,
req.body
);
res.status(200).json(response.data);
} catch (err) {
res.status(500).json({ error: 'Could not update the root' });
}
});
This is my database connection:
app.js
const express = require("express");
const app = express();
var { MongoClient } = require("mongodb");
MongoClient.connect("mongodb://localhost:27017", (err, client) => {
if (err) return console.log(err);
db = client.db("MyDb");
app.listen(5000, () => {
console.log("listening on 5000");
});
});
And this is my insert function:
router.post(
"/register",
[
check("email")
.notEmpty()
.withMessage("Email Field is empty"),
check("email")
.isEmail()
.withMessage("Your email is not valid")
],
function(req, res) {
const errors = validationResult(req);
if (errors.length >= 0) {
res.render("register", { errors: errors.errors });
console.log(errors.errors);
return;
}
const { name, email, password } = req.body;
const newUser = new User({
name: name,
email: email,
password: password
});
newUser.save(function(err) {
if (err) throw err;
console.log(true);
});
}
);
And this is my user model:
User.js
const mongoose = require("mongoose");
const UserSchema = mongoose.Schema({
name: { type: String, require: true },
email: { type: String, require: true, unique: true },
password: { type: String, require: true },
created_at: Date,
updated_at: Date
});
const User = mongoose.model("User", UserSchema);
module.exports = User;
There is no error in terminal or browser. When I click the "register" button, the app will freeze and there is no error message at all.
I already tested many tips concerning the database connection but couldn't solve the issue.
I find there are two order of problems in the proposed code, at least as we can read it in your question:
First, I can't find any binding between mongoose and the established mongodb connection
Second, your route handler does not seem to return any status code / content to the
caller
So, for as I see it, you can
change connection setup as follows
mongoose.connect('mongodb://localhost/test', {useNewUrlParser: true})
.then((conn, err) => {
app.listen(5000, () => {
console.log("listening on 5000");
});
});
in order to bind mongoose with MongoDb configuration
retust a status code, e.g. 201, when the new User has been saved:
newUser.save(function(err) {
console.log('Result', err)
if (err) throw err;
console.log(true);
res.send(201)
});
This way I prevent the application hanging up on receiving request...
I hope this can help you!
validationResult() "Extracts the validation errors from a request and makes them available in a Result object." https://express-validator.github.io/docs/validation-result-api.html Therfore, if you don't have any errors this object will contain no errors ( you can check with .isEmpty()), your endpoint doesn't send a response, and leaves the requestor waiting.
How do you implement MongoDB's Schema Validation feature in Express server? I'm working on a simple todo app and decided to use the native MongoClient instead of mongoose but i still do want to have a schema.
Base on MongoDB's docs here: https://docs.mongodb.com/manual/core/schema-validation/#schema-validation You can either create a collection with Schema or update an existing collection without schema to have one. The commands are run in the mongo shell, but how do you implement it in express?
So far what i did is make a function that returns the Schema Validation commands and call it on every routes but i get an error saying db.runCommand is not a function.
Here's my express server:
const express = require("express");
const MongoClient = require("mongodb").MongoClient;
const ObjectID = require("mongodb").ObjectID;
const dotenv = require('dotenv').config();
const todoRoutes = express.Router();
const cors = require("cors");
const path = require("path");
const port = process.env.PORT || 4000;
const dbName = process.env.DB_NAME;
let db;
const app = express();
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
MongoClient.connect(process.env.MONGO_URI,{useNewUrlParser: true},(err,client)=>{
if(err){
throw err;
console.log(`Unable to connect to the databse: ${err}`);
} else {
db = client.db(dbName);
console.log('Connected to the database');
}
});
/* Schema Validation Function */
const runDbSchemaValidation = function(){
return db.runCommand( {
collMod: "todos",
validator: { $jsonSchema: {
bsonType: "object",
required: [ "description", "responsible","priority", "completed" ],
properties: {
description: {
bsonType: "string",
description: "must be a string and is required"
},
responsibility: {
bsonType: "string",
description: "must be a string and is required"
},
priority: {
bsonType: "string",
description: "must be a string and is required"
},
completed: {
bsonType: "bool",
description: "must be a either true or false and is required"
}
}
} },
validationLevel: "strict"
} );
}
/* Get list of Todos */
todoRoutes.route('/').get((req,res)=>{
runDbSchemaValidation();
db.collection("todos").find({}).toArray((err,docs)=>{
if(err)
console.log(err);
else {
console.log(docs);
res.json(docs);
}
});
});
/* Get Single Todo */
todoRoutes.route('/:id').get((req,res)=>{
let todoID = req.params.id;
runDbSchemaValidation();
db.collection("todos").findOne({_id: ObjectID(todoID)}, (err,docs)=>{
if(err)
console.log(err);
else {
console.log(docs);
res.json(docs);
}
});
});
/* Create Todo */
todoRoutes.route('/create').post((req,res,next)=>{
const userInput = req.body;
runDbSchemaValidation();
db.collection("todos").insertOne({description:userInput.description,responsible:userInput.responsible,priority:userInput.priority,completed:false},(err,docs)=>{
if(err)
console.log(err);
else{
res.json(docs);
}
});
});
/* Edit todo */
todoRoutes.route('/edit/:id').get((req,res,next)=>{
let todoID = req.params.id;
runDbSchemaValidation();
db.collection("todos").findOne({_id: ObjectID(todoID)},(err,docs)=>{
if(err)
console.log(err);
else {
console.log(docs);
res.json(docs);
}
});
});
todoRoutes.route('/edit/:id').put((req,res,next)=>{
const todoID = req.params.id;
const userInput = req.body;
runDbSchemaValidation();
db.collection("todos").updateOne({_id: ObjectID(todoID)},{ $set:{ description: userInput.description, responsible: userInput.responsible, priority: userInput.priority, completed: userInput.completed }},{returnNewDocument:true},(err,docs)=>{
if(err)
console.log(err);
else
res.json(docs);
console.log(db.getPrimaryKey(todoID));
});
});
/* Delete todo */
todoRoutes.route('/:id').delete((req,res,next)=>{
const todoID = req.params.id;
runDbSchemaValidation();
db.collection("todos").deleteOne({_id: ObjectID(todoID)},(err,docs)=>{
if(err)
console.log(err)
else{
res.json(docs);
}
});
});
app.use('/todos',todoRoutes);
app.listen(port,()=>{
console.log(`Server listening to port ${port}`);
});
I also tried it on the initial client connection but i got the same error:
You validation schema will be added to the MongoDB driver when you run it for the first time. So you don't need to perform validation every time you run a query. You will get a validation response directly from the driver's validation schema that was added initially. Again you will not explicitly get to know which object is causing the error. The validation response will be more generic.
I am making an iOS project which uses Stripe. I am using a STPCustomerContext and the parameter to create an instance is an object of MainAPI below. When I create the instance, it automatically calls createCustomerKey() but an error (404) is throwing. The URL is "http://localhost:1337/ephemeral_keys" and I believe that is what I have everywhere but yet it is throwing a 404. Here is the code for MainAPI.swift, index.js, & api.js.
The code is:
MainAPI.swift
class MainAPI:NSObject, STPEphemeralKeyProvider {
// override init(){}
static let shared = MainAPI()
var baseURLString = Constants.BASE_URL
// MARK: STPEphemeralKeyProvider
enum CustomerKeyError: Error {
case missingBaseURL
case invalidResponse
}
func createCustomerKey(withAPIVersion apiVersion: String, completion: #escaping STPJSONResponseCompletionBlock) {
// the request
func request(id: String) {
print("creating a eph key request with customerId: \(id)") // good
let url = self.baseURLString.appending("/ephemeral_keys")
Alamofire.request(url, method: .post, parameters: [
"api_version": apiVersion,
"customerId": id
])
.validate(statusCode: 200..<300)
.responseJSON { responseJSON in
switch responseJSON.result {
case .success(let json):
print("created customer ephemeral key!")
completion(json as? [String: AnyObject], nil)
case .failure(let error):
print("could not customer ephemeral key!\n Error info: ")
print(error.localizedDescription)
completion(nil, error)
}
}
}
print("attempting to create customer ephemeral key . . .(createCustomerKey())")
let customerId = . . . // get customer id
request(id: costumerId) // this passes on the CORRECT customerId each time
}
}
api.js
var express = require('express')
var router = express.Router()
var stripe_key = process.env.STRIPE_KEY || "sk_test_myTestKey"
var stripe = require('stripe')(stripe_key);
var request = require("request-promise-native")
//API
router.get('/', function (req, res) {
res.status(200).send(JSON.stringify({ message: 'API Gateway', success: true, error: null }));
}) // Just for testing, just for error-handling
//1. Create a customer account
router.post('/new_customer', function (req, res) {
console.log("Creating new customer account...")
var body = req.body
stripe.customers.create({ email: body.email, })
.then((customer) => {
console.log(customer)
// Send customerId -> Save this for later use
res.status(200).send(JSON.stringify({ success: true, error: null, customerId: customer.id }));
})
.catch((err) => {
console.log(err)
res.status(400).send(JSON.stringify({ success: false, error: err }))
});
})
//2. Save Credit Card with token
router.post('/new_card', function (req, res) {
var customerId = req.body.customerId
var token = req.body.token
stripe.customers.update(customerId, { source: token })
.then((customer) => {
console.log(customer)
res.status(200).send(JSON.stringify({ success: true, error: null }));
})
.catch((err) => {
console.log(err)
res.status(400).send(JSON.stringify({ success: false, error: err }))
});
})
//3. Use customerId to post a charge
router.post('/new_charge', function (req, res) {
var customerId = req.body.customerId
var amount = req.body.amount
var source = req.body.source
stripe.charges.create({
amount: amount, //in cents
currency: "usd",
customer: customerId, //CUSTOMER_STRIPE_ACCOUNT_ID
source: source, // obtained with Stripe.js
}).then((charge) => {
res.status(200).send(JSON.stringify({ message: 'Sucess.', success: true, error: null }));
}).catch((error) =>{
res.status(400).send(JSON.stringify({ message: 'Error', success: false, error: error }));
})
})
// here is the error I am assuming
router.post('/ephemeral_keys', (req, res) => {
const stripe_version = req.body.api_version;
var customerId = req.body.customerId;
if (!stripe_version) {
res.status(400).end();
return;
}
console.log(stripe_version)
// This function assumes that some previous middleware has determined the
// correct customerId for the session and saved it on the request object.
stripe.ephemeralKeys.create(
{customer: customerId},
{stripe_version: stripe_version}
).then((key) => {
console.log("Ephemeral key: " + key)
res.status(200).json(key);
res.status(200).send(JSON.stringify({ message: 'AAAAhh', success: true, error: null }));
}).catch((err) => {
console.log("Ephemeral key error: " + err)
res.status(200).send(JSON.stringify({ message: 'ABBBBBB', success: true, error: null }));
res.status(500).end();
});
});
module.exports = router;
index.js
//Environment Vars
var uri = process.env.NODE_ENV || "development"
console.log(uri + " environment")
//Express App
var express = require('express');
var app = express();
//Api for reading http post request body in express
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json())
//Log Connections
app.use(function timeLog (req, res, next) {
console.log('incoming connection . . . ')
next()
})
//API middelware
var api = require('./api')
app.use('/api', api)
app.get('/', function (req, res) {
res.status(200).send(JSON.stringify({ message: 'Welcome!', success: true, error: null }));
});
//Create Server
var port = process.env.PORT || 1337;
var httpServer = require('http').createServer(app);
httpServer.listen(port, function () {
console.log('server running on port ' + port + '.');
});
When I create a STPCustomerContext (like this):
let apiKeyObject = MainAPI.shared
customerContext = STPCustomerContext(keyProvider: apiKeyObject)
The following error prints (not allowing the STPPaymentContext later to display):
Response status code was unacceptable: 404.
Please try with the below nodejs code, because syntax which your code is using might not be correct, I was using the same code as you, but later changed the implementation & deployed to firebase CLI
exports.createEphemeralKeys = functions.https.onRequest((req, res) => {
var api_version = req.body.api_version;
var customerId = req.body.customerId;
if (!api_version) {
res.status(400).end();
return;
}
stripe.ephemeralKeys.create(
{ customer: customerId },
{ stripe_version: api_version },
function(err, key) {
return res.send(key);
});
});
You might get below kind of logs.
{
id: 'ephkey_1BramAFjruqsvjkVQGdZLiV5',
object: 'ephemeral_key',
associated_objects: [ { type: 'customer', id: 'cus_CEPMtLbshv7EaP' } ],
created: 1517701830,
expires: 1517705430,
livemode: false,
secret: 'ek_test_YWNjdF8xQmxUb0FGanJ1cXN2amtWLHVPcUdMN3d4UEhncW1sQkNJYmlOdzhwUGdjVUxOd1Y'
}
For .swift file
Please Click here
Please have a look at https://www.youtube.com/watch?v=NdszUvzroxQ
I believe you need to use some remote server, instead of local server,
In my Swift file I am using .responseString instead of .responseJSON by this is I am getting success but the response is a HTML file of requesting Google Signin
I'm using Express and Sequelize to make a basic user authentication based upon this tutorial
When I want to sign a token to a user I get an error telling me I'm trying to JSON.stringify() a circular reference which cannot be done. Therefor an error is thrown and I can't assign the token to the user.
OR I am doing something wrong when finding my user in the database which makes a circular reference OR I just need to find a solution to break the circular reference I suppose. Anyone who could explain me which of the two it is?
The full error is:
TypeError: Converting circular structure to JSON
at Object.stringify (native)
at toString (/Users/Desktop/express-jwt/node_modules/jws/lib/tostring.js:9:15)
at jwsSecuredInput (/Users/Desktop/express-jwt/node_modules/jws/lib/sign-stream.js:12:34)
at Object.jwsSign [as sign] (/Users/Desktop/express-jwt/node_modules/jws/lib/sign-stream.js:22:22)
at Object.module.exports [as sign] (/Users/Desktop/express-jwt/node_modules/jsonwebtoken/sign.js:144:16)
at Model.User.findOne.then.user (/Users/Desktop/express-jwt/server/index.js:69:27)
at Model.tryCatcher (/Users/Desktop/express-jwt/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/Users/Desktop/express-jwt/node_modules/bluebird/js/release/promise.js:510:31)
at Promise._settlePromise (/Users/Desktop/express-jwt/node_modules/bluebird/js/release/promise.js:567:18)
at Promise._settlePromise0 (/Users/Desktop/express-jwt/node_modules/bluebird/js/release/promise.js:612:10)
at Promise._settlePromises (/Users/Desktop/express-jwt/node_modules/bluebird/js/release/promise.js:691:18)
at Async._drainQueue (/Users/Desktop/express-jwt/node_modules/bluebird/js/release/async.js:138:16)
at Async._drainQueues (/Users/Desktop/express-jwt/node_modules/bluebird/js/release/async.js:148:10)
at Immediate.Async.drainQueues (/Users/Desktop/express-jwt/node_modules/bluebird/js/release/async.js:17:14)
at runCallback (timers.js:574:20)
at tryOnImmediate (timers.js:554:5)
My index for the server is:
const express = require(`express`);
const app = express();
const bodyParser = require(`body-parser`);
const morgan = require('morgan');
const jwt = require('jsonwebtoken'); // used to create, sign, and verify tokens
const config = require('./config'); // get our config file
const db = require(`./models`);
const User = global.db.User;
const port = process.env.PORT || 8080;
db.sequelize.sync().then(() => {
console.log(`Express server listening on port ${port}`);
});
app.set('superSecret', config.secret);
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
app.use(morgan('dev'));
app.get('/', (req, res) => {
res.send('Hello! The API is at http://localhost:' + port + '/api');
});
app.listen(port);
console.log('Magic happens at http://localhost:' + port);
app.get('/setup', (req, res) => {
db.sequelize.sync().then(() => {
return User.create({
username: 'Kevin frafster',
password: 'password',
admin: true
})
.then(addedUser => {
console.log(addedUser.get({
plain: true
}));
})
.catch(err => {
res.json(err);
});
});
});
// API ROUTES -------------------
// get an instance of the router for api routes
const apiRoutes = express.Router();
apiRoutes.post('/authenticate', (req,res) => {
User.findOne({
where: {username: req.body.username}
}).then(user => {
if (!user) {
res.json({ success: false, message: 'Authentication failed. User not found.'});
}else{
// console.log(user);
if (user.password != req.body.password) {
res.json({ success: false, message: 'Authentication failed. Wrong password.' })
}else{
const token = jwt.sign(user, app.get('superSecret'), {
expiresIn: 60*60*24
});
res.json({
succes: true,
message: 'Enjoy your token!',
token
});
}
}
}).catch(err => {
res.status(500).json(err);
})
});
// TODO: route to authenticate a user (POST http://localhost:8080/api/authenticate)
// TODO: route middleware to verify a token
// route to show a random message (GET http://localhost:8080/api/)
apiRoutes.get('/', (req, res) => {
res.json({ message: 'Welcome to the coolest API on earth!' });
});
// route to return all users (GET http://localhost:8080/api/users)
apiRoutes.get('/users', (req, res) => {
User.findAll({})
.then(users => {
res.json(users);
})
.catch(err => {
res.json(err);
});
});
// apply the routes to our application with the prefix /api
app.use('/api', apiRoutes);
Well, the answer was totally peanuts.
1) Make new object and assign payload to it
const payload = {username: user.username, password: user.password};
2) Use the new object to assign token to
const token = jwt.sign(payload, app.get('superSecret'), {
expiresIn: 60*60*24
});