mongoose static methods not showing model document in console - express

I have a database of jobs, I am trying to create a mongoose static method to toggle a field on specific jobs to true or false. I have been trying to figure out mongoose methods and have hit a road block just trying to console.log a document to screen. I am just trying to use this.find to get a document from my mongo db whenever I run the static method but it seems to not work.
Model
const mongoose = require('mongoose');
const proxyModel = require('./proxyModel');
const User = require('./userModel');
const pendingJobModel = new mongoose.Schema({
date:{type:String, required: true, unique:true},
startTime:{type:String, required: true},
endTime:{type:String, required: true},
courseList:{type:[String], required: true},
member:{type:String},
clubUsername:{type:String, required: true},
clubPassword:{type:String, required: true},
proxy:{type:Boolean, required: true, default:false},
active:{type:Boolean, required: true, default:false},
},{collection:'pendingjobs'})
// pendingJobModel.statics.findByIdAndToggleActive = function(id, callback){
// this.find({_id:id}, callback)
// console.log('tried')
// }
pendingJobModel.static('findByID', function(id){
this.find({_id:id}, function(err, resp){
if(err){
console.log(err)
}else{
console.log(resp)
}
})
})
module.exports = mongoose.model('PendingJob', pendingJobModel)
Calling static method
async function startBot(){
console.log("[+] Bot Starting...")
const callback = function(err, resp){
if(err){
console.log(err)
}else{
console.log(resp)
}
}
PendingJob.findByID('63169a53a8944fd098f3d88b')
Why cant I see my document in console when I run the model static method??

Related

how to save specific data from json object in new state into react native

Here is my code
handleLogin = async()=> {
const { navigation } = this.props;
const errors = [];
Keyboard.dismiss();
this.setState({ loading: true });
if(this.state.email!=''){
if(this.state.password!=''){
fetch('http://192.168.1.10:8000/api/login',{
method:'post',
headers:{
'Content-Type':'application/json',
'Accept': 'application/json'
},
body:JSON.stringify({
"email":this.state.email,
"password":this.state.password
})
})
.then((response)=> response.json())
.then((res)=>{
var store=JSON.stringify(res)
this.setState({ errors, loading: false });
if(this.state.store==='{"error":"Unauthorised"}'){
Alert.alert("Error", "These credentials do not match our records");
}
else {
Alert.alert("Success","You have succesfuly login",
[
{
text: 'Continue', onPress: () => {
Actions.NavigationCalling();
}
}
],
{ cancelable: false })
}
}).catch((error)=>{
console.error(error);
});
}
else{
this.setState({ errors, loading: false });
Alert.alert("Please insert Password")
}
}
else{
this.setState({ errors, loading: false });
Alert.alert("Please insert email")
}
var store=JSON.stringify(res)
Im storing data in store variable that print output like this
{"success":{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6Ijk4YjYzNTY4NjNkNmYxNzBhYjdlYjVmNWRiN2MxNWU1NTUzNDc3OWUyZjM5Mjc5NWU4ODMzMjM3NDU1Y2Q3ODg1YzYzZTc0NDg2MmNjYzk2In0.eyJhdWQiOiIxIiwianRpIjoiOThiNjM1Njg2M2Q2ZjE3MGFiN2ViNWY1ZGI3YzE1ZTU1NTM0Nzc5ZTJmMzkyNzk1ZTg4MzMyMzc0NTVjZDc4ODVjNjNlNzQ0ODYyY2NjOTYiLCJpYXQiOjE1ODA5MzA2MzYsIm5iZiI6MTU4MDkzMDYzNiwiZXhwIjoxNjEyNTUzMDM2LCJzdWIiOiIzIiwic2NvcGVzIjpbXX0.A1NZcxICOu8mudwrIrozG5FYiQxWyz1O8LcHFcaOvgXUlTkgUIuGuwxif74goMwCLkWrm3wIwZSKwMAxCAk35Ao9VZEsV3uOlelWtsjJY7u-o00baCUl3dZWJeBHLLfSODM719Oinrfepp5VGaGZ4r--rMqMnNljVEoUP8GuM0l_7rY-SA7dhXkj4a8TwogkZOzf1_0ZvgNYmM30Z_CU0umM72Iqcys-URnzb80HONI4_cVcYExqmU94UqhNsNJ9aMIDXR4WdMGzDBzhRat_E75u7Rbt67UKUbbwALv3J1qhGRb-kkE_DGR3DyAxlcNvMy21CR4b4obDE4e96GYb-7R7fLw0PiVtiyFTgLeL2Ldvw4YV8_v2TwF5zLgkh0VCqfjUTIbAir9ytjDBPDzXFy7G4mAR6qJYNPSHtgwzBcMuS2B4FWZruWg-0QbHiBFFQrDGISaf5jUTSCmiSbpd3eTKAhiifBE6eGNnzErlsG1WAn8L7zK233l1b7qDSoahIrK4PTllgsdEzFtI4sXpy_9mEbRmGmEjOTXZcUyvkFm6aajXrRwWGrhSMFIeFqRd2BNTnrh2Igwl9x7Dcj89VgXKGXyh-hP4ESwT5yHAynNhVfhaXAu1kdnkzhwzk5cDlKlYawvX02g83THN6UAElj2bttIutM-fZ1ViLIOA98k"}}
But i want to store just token in new state and pass to other screen
how can i get only token from json object and store into newstate and pass into new screen
Thanks in advance I'm new in the React native
You can access the token by doing res.success.token or you can map the json response to an object.
.then((res)=>{
var token = res.success.token // did you try doing this?
var store=JSON.stringify(res)
this.setState({ errors, loading: false });
....
And to pass the token to another screen you can use the screen props or use redux, however, i would set it in a static variable to be accessed globally by all the screens.
I am working on a react native app that does pretty much the same that you are trying to do, i created a class called ApiService that has the following function:
static async post(url: string, payload?: object, headers?: HeadersInit_): Promise<ApiResponse> {
return await fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(payload),
}).then(r => r.json().then(o => {
var mapper = new ApiResponse();
mapper.success = o.success;
mapper.result = o.success ? JSON.stringify(o.result) : o.error;
return mapper;
})).then(response => {
if (response.success)
return response;
throw ApiError(response);
});
}
The ApiResponse class looks like this:
class ApiResponse {
public success: boolean;
public result: string;
}
To access the auth token globally, i am setting the token in a static variable in a class that can be accessed everywhere.
class AbstractService {
private static sessionToken: string;
public static setSessionToken(value: string): void {
AbstractService.sessionToken = value;
}
public static getSessionToken(value: string): string {
return AbstractService.sessionToken;
}
If you want to store the token to be reused, you can use react-native-secure-key-store

Should a new Collection be created upon Model.create()

Am working with mongoose and have two models. The User model and the Service model, when a user logs in the method will findOne() user if one exists or create() a new user based on the what's passed in from req.body.
My Service Schema is like this:
const serviceSchema = new mongoose.Schema({
name: {
type: String,
default: 'contentEditor'
},
display: {
type: String,
default: 'Content Editor'
},
accessLevel: {
type: Number,
min: 0,
max: 4,
default: 4
}
});
My User Schema is a bit bigger, I've removed some of the field/value pairs but the part where I embed the Service Schema looks like this:
const userSchema = new mongoose.Schema(
{
email: {
type: String,
required: [true, 'Must have a email address'],
trim: true,
unique: true,
},
firstName: {
type: String,
},
lastName: {
type: String,
},
services: {
type: [serviceSchema],
ref: 'Services',
default: [serviceSchema],
},
},
);
When I hit the /api/v1/login endpoint a new user will be created with the Service document correctly but within the Mongoose database only a User collection exists. How do I make it so that both a Users collection and Services collection are created?
Edit: Below is the function that I create/find the user with when they login. When an existing User is found, by their email it will return that user if the user is not found then it will create a new one...
Both behaviours are as expected including adding the Services to the newly created User. What isn't expected is that only ONE collection is added to the DB.
const login = catchAsync(async ({ body: { email, password } }, res, next) => {
if (!email || !password) {
return next(new AppError('Please provide email and password', 400));
}
const { Success } = await webApi(email, password);
const mongoUser = await User.findOne({ email });
if (Success && mongoUser) {
return createSendtoken(mongoUser, 200, res);
}
if (Success && !mongoUser) {
const newUser = await User.create({ email });
return createSendtoken(newUser, 201, res);
}
return next(new AppError('User not found', 404));
});
Make sure you are making the serviceSchema a mongoose model.
const Services = mongoose.model('Service', serviceSchema)
You also have to save it using mongooses model.save() function

Chai test a mongoose Promise

I am really struggling with Chai testing especially now that I have started using mongoose Promises and Async/Await.
Apologies in advance for the long post, but each part is necessary to form a bigger picture.
This is a Message Board app (FCC for anyone familiar).
3 models for Board, Thread, Reply with Ref.
My Thread Schema needs a Board _id when created.
In my Chai test I am hardcoding a message Board _id. This Thread Object does get created in the database but the board field is not added and I can't understand why.
The second issue is that the CHAI test does not return a body in the response - it returns {}. So I have nothing to run asserts against. The newThread function does return a data object from the new_thread.save(function (err, data), as I had the new _id to the Board/threads sub-document array
Thread Schema
const ThreadSchema = new Schema({
"text": {'type': String},
"delete_password": { 'type': String,'select': false},
"created_on": {'type': Date, 'default': new Date()},
"bumped_on": {'type': Date, 'default': new Date()},
"reported": {'type': Boolean,'select': false,'default': false},
"replycount":{'type': Number,'default': 0},
"board": {'type': mongoose.Schema.Types.ObjectId,'ref': 'Board'},
"replies": [{'type': mongoose.Schema.Types.ObjectId,'ref': 'Reply'}]
});
Create a Thread function
this.newThread = function(req, res) {
let threadText = req.body.text;
let passwordText = req.body.delete_password;
let boardTitle = req.params.board;
const new_thread = new models.Thread({
text: threadText,
delete_password: passwordText,
board:currentBoardId //currentBoardId defined & set earlier
});
new_thread.save(function (err, data) {
models.Board
.findOne({ board_title: boardTitle})
.then(board => {
if (board == null) {
res.json({ message: "Cannot find board named, " + boardTitle });
} else {
board.threads.push(data._id);
board.save(function (err){
if (err) {console.log(err);}
res.end();
});
}
})
.catch(err => {
return res.status(500).json({ message: err.message })
})
})
};
CHAI test
test('Every field filled in', function(done) {
chai.request(server)
.post('/api/threads/test')
.send({
board: ObjectId('5d8f748a1d788a3be2b9a7b7'), // board test _id Never gets added to database
text: 'POST - new thread - test thread text',
delete_password: 'password'
})
.end(function(err, res){
expect(err).to.be.null;
assert.equal(res.status, 200);
console.log(res.body); // returns {}
done();
});
});

profile validation failed: handle: Path `handle` is required

My goal is to build an app that will connect different professionals from different background. I'm also using mongoose as my database.
I created a profile.js that will create and update profiles. But when I test with postman, I get the following error:
"PROFILE VALIDATION FAILED: HANDLE: PATH HANDLE IS REQUIRED."
What can I possibly do to solve this issue?
Your help will be grateful.
const express = require('express'); // require express modules
const router = express.Router(); // to use express router
const auth = require('../../middleware/auth');
const { check, validationResult } = require('express-validator');
const Profile = require('../../models/Profile');
const User = require('../../models/User');
//#route GET api/profile/me
//#desc Get current users profile
//#access Private
router.get('/me', auth, async (req,res) => {
try{
const profile = await Profile.findOne({user: req.user.id}).populate(
'user',
['name', 'avatar']);
if(!profile){
return res.status(400).json({ msg:'No profile exists for this user'});
}
res.json(profile);
} catch(err){
console.error(err.message);
res.status(500).send('Server error');
}
}); //to create a route
//#route POST api/profile
//#desc Create or update users profile
//#access Private
router.post('/',
[
auth,
[
check('status', 'Status is required')
.not()
.isEmpty(),
check('skills', 'Skills is required')
.not()
.isEmpty()
]
] ,
async (req, res) =>{
const errors = validationResult(req);
if(!errors.isEmpty()){
return res.status(400).json({errors: errors.array()})
}
const {
company,
website,
location,
bio,
status,
githubusername,
skills,
youtube,
facebook,
twitter,
instagram,
linkedin
} =req.body;
//to build profile object
const profileFields = {};
profileFields.user = req.user.id
if(company) profileFields.company = company;
if(website) profileFields.website = website;
if(location) profileFields.location = location;
if(bio) profileFields.bio = bio;
if(status) profileFields.status = status;
if(githubusername) profileFields.githubusername = githubusername;
if(skills){
profileFields.skills = skills.split(',').map(skills => skills.trim());
}
//for the social object
profileFields.social = {}
if(youtube) profileFields.social.youtube = youtube;
if(facebook) profileFields.social.facebook = facebook;
if(twitter) profileFields.social.twitter = twitter;
if(instagram) profileFields.social.instagram = instagram;
if(linkedin) profileFields.social.linkedin = linkedin;
try{
let profile = await Profile.findOne({ user: req.user.id });
if(profile){ //if there is a profile, we will update it
profile = await Profile.findOneAndUpdate(
{ user: req.user.id},
{$set: profileFields },
{new: true}
);
return res.json(profile);
}
//this will create profiles
profile = new Profile(profileFields);
await profile.save();
res.json(profile);
} catch(err){
console.error(err.message);
res.status(500).send('Server Error');
}
}
);
module.exports = router;
same code, same issue. In the profile Schema there is a handle field that is set to required. i commented it out and it is working fine now.
the same code you made i made it,you will found handle is required in profile model delete it and your code will working
handle: {
type: String,
required: true,
max: 40
}
Change this code in your models/Profile.js to
handle: {
type: String,
required: false,
max: 40
},
I had the very same Issue . However , it happened because in your "Profile" Schema you probably you made the 'handle' attribute required . So , you must have to give it otherwise just make a change and make the require value to false . Such as (require: false) and hopefully your issue will go .
This is happening because your Profile schema has a handle field(attribute) in which you have a property required: true.
Go to the profile schema file and remove the handle attribute(field) or remove the required: true< from the handle attribute
Example
Profile.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Create Schema
const Profile = new Schema({
...,
handle: {
type: ...,
required: true //remove this line
}
...
});
use
let const profileFields = {};
profileFields.user = req.user.id
that's
let profileFields = {};
profileFields.user = req.user.id
or you can use
const profileFields = {};
profileFields.user = req.user.id;

Testing angular services in rails

I'm trying to test my services with jasmine and I keep gettin and "Unknown provider: AuthServiceProvider <- AuthService in angular/angular.js on line 2683"
my service is defined:
app.factory( 'AuthService', ["$resource", "$rootScope", "apiPrefix", function($resource, $rootScope, apiPrefix) {
auth_resource = $resource(apiPrefix + "/session", {}, {
logout: {method:'GET'}
});
var currentUser;
return {
login: function(email, password, success, failure) {
auth_resource.save({}, {
email: email,
password: password
}, function(response){
currentUser = response
success()
}, function(response){
failure()
});
},
logout: function(success, failure) {
auth_resource.logout(
function(response){
currentUser = undefined
}, function(){
$scope.alerts.push({type: "success", msg: "Logged out" })
}, function(){
$scope.alerts.push({type: "error", msg: "Sorry, something went wrong" })
}
)
},
isLoggedIn: function(){ return currentUser !== undefined},
currentUser: function() { return currentUser; }
};
}]);
and my test:
describe("AuthService", function(){
var httpBackend;
beforeEach(inject(function($httpBackend, AuthService){
module('app');
httpBackend = $httpBackend;
AService = AuthService;
}));
it("should login the user", function(){
// test here
});
});
my jasmine config file is:
// This pulls in all your specs from the javascripts directory into Jasmine:
// spec/javascripts/*_spec.js.coffee
// spec/javascripts/*_spec.js
// spec/javascripts/*_spec.js.erb
//= require application
//= require_tree ./
This seems to be configured properly because I can test my controllers fine so I'm not sure why it doesn't recognize my services.
You can use $injector to get the service and then inject it to the actual test like this
describe("AuthService", function () {
var httpBackend, AService, apiPrefix;
beforeEach(module('app'));
beforeEach(function () {
angular.mock.inject(function ($injector) {
httpBackend = $injector.get('$httpBackend');
apiPrefix = angular.mock.module('apiPrefix'); // I assume you have apiPrefix module defined somewhere in your code.
AService = $injector.get('AuthService', {apiPrefix: apiPrefix});
})
});
it("should login the user", inject(function (AService) {
// test here
}));
});
I assume you have apiPrefix module defined somewhere in your code.