consuming a rest api inside Express: userid not found - node.js

Insprirated on Gettin MEAN I am making my own application. I try to connect to front end to the backend in Express. I copied the text but my console.log still giving me the message 'userid not found'. I think I am pretty close to the finish. Any tips or helpful links are appreciated.
the Usermodel
const userSchema = new Schema({
firstName: String,
lastName: String,
userName: String,
telephone: String,
password: String
});
2. the route in the api
router
.route('/users/:userid')
.get(ctrlUsers.userReadOne);
module.exports = router;
In Postman this get.request works (for example)
http://localhost:3000/api/users/5ad87da47bb05b0594fff5b6
Together with the book I programmed the app/server/controller:
route:
const express = require('express');
const router = express.Router();
const ctrlUsers = require('../controllers/users');
router.get('/users/:userid', ctrlUsers.userInfo);
module.exports = router;
and the controllers. Here my console.log gives 'no userid found'
const request = require('request');
const apiOptions = {
server: 'http://localhost:3000'
};
if (process.env.NODE_ENV === 'production') {
apiOptions.server = 'https://pure-temple-67771.herokuapp.com';
}
/*Get myprofile */
const userInfo = function (req, res) {
const path = '/api/users/${req.params.userid}';
requestOptions = {
url: apiOptions.server + path,
method: 'GET',
json: {}
};
console.log('path ' + requestOptions.url);
request(
requestOptions,
(err, response, body) => {
_rendermyProfile(req, res, body);
console.log(body); // no userid found
});
};
const _rendermyProfile = function (req, res, userDetail) {
res.render('myProfile', {
profile: {
title: 'Mijn profiel',
firstName: userDetail.firstName,
lastName: userDetail.lastName,
email: userDetail.email,
telephone: userDetail.telephone
}
});
};
module.exports = {
userInfo
};

Of course you will get no userid found, because you have a misusage of string literal. Inside your controller, changed from this:
const path = '/api/users/${req.params.userid}';
to this:
const path = `/api/users/${req.params.userid}`;
String literal is only working if you used a back slash `.
Now your App should make a request correctly.

Related

Vue 3 / Express params returning their name

First off let me say sorry if the title of the question confused anyone reading my question. I didn't know how to best word my question. The issue I'm having is when I try to send a get request from my axios instance to my express instance. When I send data from axios, I have my object showing all the data it needs but when I try to utilize that data in express using req.params.email the value its holding is :email heres my code:
Client/Axios
checkEmail (data) {
return http.get('/users/:email', data)
},
Value of 'data' Object
{email: 'ThisIs#MyEmail.Org'}
Server/Express
router.get('/users/:email', function (req, res) {
console.log(req.params.email)
const data = User.find({ email: req.params.email })
return res.sendStatus(200).json(data)
})
Server Console Log
{ email: ':email' }
As a side note I have tried to just use req.params but it returns the same thing. If anyone can point out what I'm doing wrong I would greatly appreciate it!
This code will works.
You needs to switch from hard code data
to your const data = User.find({ email: req.params.email })
From
const data = {
email: 'test#gmail.com',
first_name: 'Tom',
last_name: 'Cruise'
}
To
const data = User.find({ email: req.params.email })
server.js
const express = require("express")
const axios = require('axios')
const cors = require("cors")
const app = express()
app.use(cors())
app.get("/users/:email", async (req, res) => {
console.log("params", req.params);
// const data = User.find({ email: req.params.email })
const data = {
email: 'test#gmail.com',
first_name: 'Tom',
last_name: 'Cruise'
}
res.status(200).json(data);
});
app.listen(3000, () => { console.log("Listening on :3000") })
client.js
const axios = require('axios')
const checkEmail = async (data) => {
try {
const response = await axios.get(`http://localhost:3000/users/${data}`);
return Promise.resolve(response.data)
} catch (error) {
return Promise.reject(error)
}
};
checkEmail('ThisIs#MyEmail.Org')
.then(result => {
console.log('user is : ' + JSON.stringify(result))
})
.catch(error => {
console.log(error.message)
});
Install dependencies
npm install express axios cors
Run first server
node server.js
Run second client
node client.js
Result at server
Result at client

After PassportJS Authentication Sign Up How can you Register that user to mailchimp list?

Good Morning, I am trying to get user information from a signup form that is posting to my Mongo Database to then sign a user up to Mailchimp. The code I current am working with is:
require("dotenv").config();
const express = require("express"),
expressSanitizer= require("express-sanitizer"),
router = express.Router(),
passport = require("passport"),
User = require("../models/user"),
middleware = require("../middleware"),
superagent = require('superagent'),
mailchimp = require('#mailchimp/mailchimp_marketing'),
request = require('request'),
https = require('https');
//REGISTER USER
router.post("/register", function (req, res){
var newUser = {
firstName: req.sanitize(req.body.firstName),
lastName: req.sanitize(req.body.lastName),
email: req.sanitize(req.body.email),
username: req.sanitize(req.body.username)
};
User.register(newUser, req.body.password, function(err,user){
if(err){
// DISPLAYS PASSPORT ERROR
console.log(err);
return res.render("/login");
}
passport.authenticate("local")(req, res, function(){
console.log(user);
res.redirect("/insider/resources");
});
});
// Mailchimp Logic
const firstName = req.sanitize(req.body.firstName);
const lastName = req.sanitize(req.body.lastName);
const email = req.sanitize(req.body.email);
var data = {
members:[ {
email_address: email,
status: "subscribed",
merge_fields: {
FNAME: firstName,
LNAME: lastName
}
}]
};
var jsondata = JSON.stringify(data);
const url = `https://us3.api.mailchimp.com/3.0/lists/`+process.env.MAILCHIMPLIST;
const options = {
method: "POST",
body: data,
auth: process.env.MAILCHIMP
};
const request = https.request(url, options, function(response){
response.on("data", function (data) {
console.log(JSON.parse(data));
});
if(response.statusCode === 200){
res.render("/insider/resources");
} else {
res.render("landing");
}
});
request.write(jsondata);
request.end();
});
In this example process.env.MAILCHIMP is my stored API, process.env.MAILCHIMPLIST is the audience I want to drop the users into.
A This point I know the user is registered because my console.log() shows the user registered in Mongo. After this I get this error from Mailchimp's API:
{
type: 'https://mailchimp.com/developer/marketing/docs/errors/',
title: 'API Key Invalid',
status: 401,
detail: "Your API key may be invalid, or you've attempted to access the wrong datacenter.",
instance: '40471ba2-403c-9846-ef76-f3cb6b39087f'
}
If anyone could help me find where I am making a mistake I would greatly appreciate it.
I realized after looking at my code I did not have two dependencies installed, thank you to anyone who tried to help, but the exact code to make this work is :
// REQUIREMENTS
require("dotenv").config();
const express = require("express"),
expressSanitizer= require("express-sanitizer"),
router = express.Router(),
passport = require("passport"),
User = require("../models/user"),
mailchimp = require('#mailchimp/mailchimp_marketing'),
request = require('request'),
https = require('https');
// Mailchimp Logic in your route
let firstName = req.sanitize(req.body.firstName);
let lastName = req.sanitize(req.body.lastName);
let email = req.sanitize(req.body.email);
var data = {
members:[ {
email_address: email,
status: "subscribed",
merge_fields: {
FNAME: firstName,
LNAME: lastName
}
}]
};
var jsonData = JSON.stringify(data);
const url = 'https://us3.api.mailchimp.com/3.0/lists/'+process.env.MAILCHIMPLIST;
const options = {
method: "POST",
auth: "archit:"+process.env.MAILCHIMPAPI,
};
const request = https.request(url, options, (response) => {
response.on("data", (data) => {
console.log(JSON.parse(data));
});
});
request.write(jsonData);
request.end();

Attribute not submitting to MongoDB (MERN stack)

I'm working on an app that assesses students algebra 1 level. I'm trying to send a string called "answers" to the database, but nothing is ever sent. I've shown the model/schema below, where basically each submission should send the answers String (it was originally an object, but I couldn't get an answer to Mongoose not persisting object so I'm just trying a string to see if it even submits a string. The user and date are submitted to the database, but there is not even an entry for the answers attribute. I've seen that the payload sent if I submit a "2" is {"results": "2"} so there's something in the request body. My response back from the server is {} so I think I'm not destructuring a prop correctly or maybe sending an object unintentionally.. Any ideas as to why no answers attribute is submitted to the database? Any help is greatly appreciated!
api/algebra1.js (route to send test results)
const express = require('express');
const router = express.Router();
var bodyParser = require('body-parser')
const bcrypt = require('bcryptjs');
const algebra1 = require('../../models/Algebra1');
const jwt = require('jsonwebtoken');
const config = require('config');
const auth = require('../../middleware/auth');
//#route POST api/auth
//#desc Algebra 1 route
//#access Private
var jsonParser = bodyParser.json();
router.post('/', [jsonParser, auth], async (req, res) => {
const { answers } = req.body;
try {
let newTest = new algebra1({
answers: answers,
user: req.user.id,
date: Date.now()
})
console.log("body is " + req.body)
await newTest.save();
res.json({ answers: answers });
} catch (err) {
console.error(err.message);
res.status(500).send('Server error');
}
})
module.exports = router;
Algebra1.js (model for Mongoose):
const mongoose = require('mongoose');
const Algebra1Schema = new mongoose.Schema({
answers: {
type: String
},
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'user'
},
date: {
type: Date,
default: Date.now
}
})
module.exports = algebra1 = mongoose.model('algebra1', Algebra1Schema)
submit action (submits results to api/algebra1 route):
export const submit = (results) => async dispatch => {
try {
const config = {
headers: {
'Content-Type': 'application/json'
}
}
console.log(results);
const body = JSON.stringify({ results });
const res = await axios.post('/api/algebra1', body, config);
dispatch({
type: QuestionActionTypes.RESET
})
dispatch(setAlert('You\;ve finished your assessment!', 'success'));
} catch (err) {
console.error(err.message);
}
}
You are sending data with results key and destructing as answer key. Where are you sending anything against answer key ? I guess you meant to submit results as answers.
const body = JSON.stringify({ answers: results });

Why can't I return the password from my MERN stack app in Postman?

In NodeJS the 'password:' string becomes an empty string somehow. Any other string with any other name can be returned, but I cannot return the 'password'. By process of elimination I have discovered only the word 'password' becomes an empty string for some reason. I cannot return it. I cannot encrypt it. I cannot do anything to it.
This isn't just a problem with Postman because when I try to do anything with the 'password' element I get the error [0] Error: Illegal arguments: undefined, string in Node.
When I do a post to the route with Postman I get no response with the code below.
If I change the line res.json(newUser.password) in the routes file below to res.json(newUser.email) the route returns the email.
I am following along with a video here. It is set to jump to the time in question if you click on the link. It was filmed thirteen months after making this post, so maybe something changed to protect passwords.
At first I was trying to encrypt the password but I have discovered it is just an empty string. Has it been encrypted somewhere?
In my routes folder
const express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs')
const path = require('path');
const crypto = require('crypto');
const MongoClient = require('mongoose');
const multer = require('multer');
const GridFsStorage = require('multer-gridfs-storage');
const Grid = require('gridfs-stream');
const config = require('config');
// Mongo URI
const mongoURI = 'mongodb://localhost:27017/fuzz';
// Create mongo connection
const conn = MongoClient.createConnection(mongoURI, {
useNewUrlParser: true,
useCreateIndex: true });
const User = require('../../models/User')
// Init gfs
let gfs;
conn.once('open', () => {
// Init stream
gfs = Grid(conn.db, MongoClient.mongo);
gfs.collection('zoo');
});
// Create storage engine
const storage = new GridFsStorage({
url: mongoURI,
file: (req, file) => {
return new Promise((resolve, reject) => {
crypto.randomBytes(16, (err, buf) => {
if (err) {
return reject(err);
}
const filename = buf.toString('hex') + path.extname(file.originalname);
const fileInfo = {
filename: filename,
bucketName: 'zoo'
};
resolve(fileInfo);
});
});
}
});
const upload = multer({ storage });
// #route POST api/users
// #desc Register new user
// #access Public
router.post('/', (req, res) => {
const { name, email, password } = req.body;
// Simple Validation
if(!name || !email || !password) {
return res.status(400).json({msg: 'Please enter all fields' });
}
// Check for existing user
User.findOne({ email })
.then(user => {
if(user) return res.status(400).json({msg: 'User already exists'})
const newUser = new User({
name,
email,
password
});
res.json(newUser.password)
})
});
module.exports = router;
The model for the route above
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Create Schema
const UserSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
unique: true
},
password: {
type: String,
required: true
},
register_date: {
type: Date,
default: Date.now
}
});
module.exports = User = mongoose.model('user', UserSchema);

Microsoft Graph API with Simple-OAuth2 and Client Credentials Flow

I'm trying to log users with Client Credentials Flow with Simple-OAuth2 in a NodeJS website.
My routes/index.js is this:
var express = require('express');
var router = express.Router();
var authHelper = require('../helpers/auth');
router.get('/', async function(req, res, next) {
let parms = { title: 'Home', active: { home: true } };
const accessToken = await authHelper.accessToken;
res.render('index', parms);
});
module.exports = router;
And my auth.js is this:
const credentials = {
client: {
id: process.env.APP_ID,
secret: process.env.APP_PASSWORD,
},
auth: {
tokenHost: 'https://login.microsoftonline.com',
authorizePath: "common/oauth2/v2.0/authorize",
tokenPath: "common/oauth2/v2.0/token",
}
};
const oauth2 = require('simple-oauth2').create(credentials);
const tokenConfig = {
username: 'uuuuuu#dddddd.com',
password: 'ppppppp',
scope: process.env.APP_SCOPES,
};
try {
const result = await oauth2.ownerPassword.getToken(tokenConfig);
const accessToken = oauth2.accessToken.create(result);
} catch (error) {
console.log('Access Token Error', error.message);
}
exports.accessToken = accessToken;
When I try to start website, nodejs shows me a sintax error:
const result = await oauth2.ownerPassword.getToken(tokenConfig);
^^^^^
SyntaxError: await is only valid in async function
This error does not make much sense to me since the code is provided by simple-oauth2.
Could someone shed light on my actual error?
Well you have to wrap your code into async function so you could use await key word in that function. You cna find more info here.
In your case I would wrap code into function and export that function like this:
const credentials = {
client: {
id: process.env.APP_ID,
secret: process.env.APP_PASSWORD,
},
auth: {
tokenHost: 'https://login.microsoftonline.com',
authorizePath: "common/oauth2/v2.0/authorize",
tokenPath: "common/oauth2/v2.0/token",
}
};
const oauth2 = require('simple-oauth2').create(credentials);
const tokenConfig = {
username: 'uuuuuu#dddddd.com',
password: 'ppppppp',
scope: process.env.APP_SCOPES,
};
const getAccessToken = async () => {
try {
const result = await oauth2.ownerPassword.getToken(tokenConfig);
const accessToken = oauth2.accessToken.create(result);
return accessToken;
} catch (error) {
console.log('Access Token Error', error.message);
return null;
}
};
exports.getAccessToken = getAccessToken;
And then you can use that function like this:
var express = require('express');
var router = express.Router();
var authHelper = require('../helpers/auth');
router.get('/', async function(req, res, next) {
let parms = { title: 'Home', active: { home: true } };
const accessToken = await authHelper.getAccessToken();
res.render('index', parms);
});
module.exports = router;

Resources