URL not saved in File Field object - node.js

I have used File Field to upload files it working fine but File URL not saved in DB.
File object
benifitsFile
Object:filename:
"srrfnKNvcQ1zTOup.pdf"
size:878742
mimetype:"application/pdf"
I have to define a storage path and add filed type.
var Storagepath = new keystone.Storage({
adapter: keystone.Storage.Adapters.FS,
fs: {
path: '/public/uploads',
publicPath: '/public/uploads/',
},
});
Course.add({
title: { type: String, required: true, initial: true},
headerimage: { type: Types.CloudinaryImage,label:'Header Image' },
benifitsFile: { type: Types.File, storage: Storagepath ,label:'Upload features & benifits file'},
questions: { type: Types.Relationship, ref: 'Question', index: true,many:true }
});
Thanks

Finally, I found a solution.
var Storagepath = new keystone.Storage({
adapter: keystone.Storage.Adapters.FS,
fs: {
path: keystone.expandPath('./public/uploads'),
publicPath: './public/uploads',
},
schema: {
size: true,
mimetype: true,
path: true,
originalname: true,
url: true,
},
});

Related

No automatic _id generated

So I have this code for adding a new item to the database, like so:
let parking = new Parking({
name: req.body.name,
country: mongoose.Types.ObjectId(req.body.country),
reservationsEmail: req.body.reservationsEmail,
location: mongoose.Types.ObjectId(req.body.location),
commissionPercentage: req.body.commission,
isConcept: true,
});
parking.save()
.then(parking => {
res.send(parking);
}).catch(err => {
res.send(err);
});
This gives me an error that _id is required before saving:
{ MongooseError: document must have an _id before saving
at new MongooseError (/Users/robin/www_node/parkos/node_modules/mongoose/lib/error/mongooseError.js:14:11)
at Timeout._onTimeout (/Users/robin/www_node/parkos/node_modules/mongoose/lib/model.js:259:18)
at ontimeout (timers.js:466:11)
at tryOnTimeout (timers.js:304:5)
at Timer.listOnTimeout (timers.js:267:5)
message: 'document must have an _id before saving',
name: 'MongooseError' }
Why isn't the _id automatically added like it supposed to?
This is the model I use:
const mongoose = require('mongoose');
const ObjectId = mongoose.Schema.ObjectId;
const isEmail = require('validator/lib/isEmail');
const slugify = require('../../lib/utils.js').slugify;
let parkingSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
slug: {
type: String,
required: true,
default() {
return slugify(this.name);
}
},
country: {
type: ObjectId,
ref: 'Country',
required: true,
},
reservationsEmail: {
type: String,
required: true,
validate: [
isEmail,
'Please enter a valid emailaddress'
],
},
discountPercentage: {
type: String,
required() {
return !this.isConcept;
},
default: 0,
},
location: {
type: ObjectId,
required: true,
ref: 'Location'
},
commissionPercentage: {
type: Number,
required: true,
},
isConcept: {
type: Boolean,
required: true,
default: false,
},
active: {
type: Boolean,
default: true,
},
}, {
timestamps: true,
});
const Parking = mongoose.model('Parking', parkingSchema);
module.exports = Parking;
Values for both country and location in request:
console.log('Location', parking.location, typeof parking.location); // Location 5caa0993ab95691762dc1a33 object
console.log('Country', parking.country, typeof parking.country); // Country 5caa04e6b6969a708080f8dd object
So when I post it via Postman:
{
"name": "Test Parking",
"reservationsEmail": "example#gmail.com",
"country": "5caa04e6b6969a708080f8dd",
"location": "5caa0993ab95691762dc1a33",
"commission": "20"
}
It works like expected... via the Fetch API though...
let formData = new URLSearchParams([...new FormData(form).entries()]);
fetch('/parkings/create-concept', {
method: "POST",
body: formData,
credentials: "include",
}).then(response => {
console.log(response);
}).catch(err => {
console.log(err);
});
In your model.js have you this line ?
module.exports = mongoose.model('Parking', parkingSchema);
=======================
Country and location must be instance of objectId, try to set them with
mongoose.Types.ObjectId(req.body.myfield);

Dynamic type select in keystonejs model

I would like to use a combobox at the adminUI with fields that come from a webservice. I was thinking on get the data with a pre 'find' hook and then override the options atribute at the 'audience' property in the Schema.
Schema:
Compliance.add({
title: { type: Types.Text, required: true, initial: true, index: true },
url: { type: Types.Url, required: true, initial: true },
position: { type: Types.Number, initial: true },
audience: { type: Types.Select, options: [], many: true, initial: true},
});
Hook:
Compliance.schema.pre('find', async function(next) {
let audiences = await audienceService.getAudiences();
next();
})
But I didn't find the way to bind the data. Any ideas how this can be done?
Thanks
You can try making a function from the options:
function getAudiences() {
return ['a', 'b', 'c'];
}
Compliance.add({
title: { type: Types.Text, required: true, initial: true, index: true },
url: { type: Types.Url, required: true, initial: true },
position: { type: Types.Number, initial: true },
audience: { type: Types.Select, many: true, initial: true, options: getAudiences() }
});
Result as below:

Populating related keystone list

So I have a Post model (built in of course). Each Post has an Author. Each Author has a Profile (I built this out separately deliberately as I am trying to learn. I am having real problems populating the profile
Here's what I have in my blog.js
// Load the posts
view.on('init', function(next) {
var q = keystone.list('Post').paginate({
page: req.query.page || 1,
perPage: 10,
maxPages: 10
})
.where('state', 'published')
.sort('-publishedDate')
.populate('categories')
.populate('author');
if (locals.data.category) {
q.where('categories').in([locals.data.category]);
}
q.exec(function(err, results) {
locals.data.posts = results;
async.each(results.results, function(post,_next) {
post.author.populate('profile', function(err, author) {
post.author = author;
locals.data.posts.results.push(post);
_next();
});
}, function(err) {
next();
})
})
});
Here is Profile
var keystone = require('keystone'),
Types = keystone.Field.Types;
var Profile = new keystone.List('Profile', {
map: { name: 'nickname' },
autokey: { path: 'slug', from: 'nickname', unique: true }
});
Profile.add({
nickname: { type: String, required: true, initial: true},
age: { type: Types.Number, initial: false, required: false, index: true },
location: { type: Types.Text, initial: false, required: false, index: true }
});
Profile.defaultColumns = 'nickname, age, location';
Profile.register();
Here is user
var keystone = require('keystone'),
Types = keystone.Field.Types;
/**
* User Model
* ==========
*/
var User = new keystone.List('User');
User.add({
name: { type: Types.Name, required: true, index: true },
email: { type: Types.Email, initial: true, required: true, index: true },
password: { type: Types.Password, initial: true, required: true },
profile: { type: Types.Relationship, ref: 'Profile', index: true },
}, 'Permissions', {
isAdmin: { type: Boolean, label: 'Can access Keystone', index: true }
});
// Provide access to Keystone
User.schema.virtual('canAccessKeystone').get(function() {
return this.isAdmin;
});
/**
* Relationships
*/
User.relationship({ ref: 'Post', path: 'posts', refPath: 'author' });
/**
* Registration
*/
User.defaultColumns = 'name, email, isAdmin';
User.register();
Here is Post
var keystone = require('keystone'),
Types = keystone.Field.Types;
/**
* Post Model
* ==========
*/
var Post = new keystone.List('Post', {
map: { name: 'title' },
autokey: { path: 'slug', from: 'title', unique: true }
});
Post.add({
title: { type: String, required: true },
state: { type: Types.Select, options: 'draft, published, archived', default: 'draft', index: true },
author: { type: Types.Relationship, ref: 'User', index: true },
publishedDate: { type: Types.Date, index: true, dependsOn: { state: 'published' } },
image: { type: Types.CloudinaryImage },
content: {
brief: { type: Types.Html, wysiwyg: true, height: 150 },
extended: { type: Types.Html, wysiwyg: true, height: 400 }
},
categories: { type: Types.Relationship, ref: 'PostCategory', many: true }
});
Post.schema.virtual('content.full').get(function() {
return this.content.extended || this.content.brief;
});
Post.defaultColumns = 'title, state|20%, author|20%, publishedDate|20%';
Post.register();
Thanks in advance!

Image gallery with caption using CloudinaryImage on keystonejs

I'm using keystonejs and CloudinaryImages to create an Image Gallery.
{ type: Types.CloudinaryImages }
I need the ability to add a caption to the images.
I was also reading this:
https://github.com/keystonejs/keystone/pull/604
but I could not figure out if this option is already in place or not.
Any idea?
Thanks.
I had a similar problem, I wanted to be able to give Images there own descriptions and other attributes, while also being included in a Gallery with a Gallery description.
This may be more than you are looking for but here is a Image model:
var keystone = require('keystone'),
Types = keystone.Field.Types;
/**
* Image Model
* ==================
*/
var Image = new keystone.List('Image', {
map: { name: 'name' },
autokey: { path: 'slug', from: 'name', unique: true }
});
Image.add({
name: { type: String, required: true },
image: { type: Types.CloudinaryImage, autoCleanup: true, required: true, initial: false },
description: { type: Types.Textarea, height: 150 },
});
Image.relationship({ ref: 'Gallery', path: 'heroImage' });
Image.relationship({ ref: 'Gallery', path: 'images' });
Image.register();
And the Galleries that contain these images looks like this:
var keystone = require('keystone'),
Types = keystone.Field.Types;
/**
* Gallery Model
* =============
*/
var Gallery = new keystone.List('Gallery', {
map: { name: 'name' },
autokey: { path: 'slug', from: 'name', unique: true }
});
Gallery.add({
name: { type: String, required: true},
published: {type: Types.Select, options: 'yes, no', default: 'no', index: true, emptyOption: false},
publishedDate: { type: Types.Date, index: true, dependsOn: { published: 'yes' } },
description: { type: Types.Textarea, height: 150 },
heroImage : { type: Types.Relationship, ref: 'Image' },
images : { type: Types.Relationship, ref: 'Image', many: true }
});
Gallery.defaultColumns = 'title, published|20%, publishedDate|20%';
Gallery.register();
You will need to create Template Views and Routes to Handle this, but it isn't too much more work - these are just the Models - let me know if you would like me to post the routes I am using for this, I am using Handlebars for my views so that may not be as helpful.

combobox's Value is not load in extjs MVC

I am working with ExtJS MVC and implementing Scheduler.
I want to load my Store in my combo box but it was not load successfully.
My Store is
Ext.define('gantt.store.serviceStore', {
extend: 'Ext.data.Store',
model: 'gantt.model.Service',
storeId: 'serviceStore',
autoLoad: true,
autoSync: true,
proxy: {
type: 'ajax',
api: {
read: 'Event/Get'
},
reader: {
type: 'json',
root: 'data'
},
writer: {
type: 'json',
encode: true,
writeAllFields: true,
root: 'data'
}
}
});
My Model is
Ext.define('gantt.model.Service', {
extend: 'Sch.model.Event',
fields: [{ name: 'ServiceId' },
{ name: 'ServiceName' },
{ name: 'Description' },
{ name: 'Rate' }
],
proxy: {
type: 'ajax',
api: {
read: 'Service/Get'
},
reader: {
type: 'json',
root: 'data'
},
writer: {
root: 'data',
type: 'json',
encode: true,
writeAllFields: true
}
}
});
and My ComboBox Code is below..
this.combo = new Ext.form.ComboBox({
id: 'statesCombo',
store: 'serviceStore',
displayField: 'ServiceName',
valueField: 'ServiceName',
hiddenName: 'ServiceId',
typeAhead: true,
mode: 'local',
fieldLabel: 'Services',
anchor: '100%',
forceSelection: true,
triggerAction: 'all',
emptyText: 'Select a Service',
selectOnFocus: true })
My Problem is when I am Click on combo box my value is not loaded..
and didnt display any Error.
You're missing the "name" option... Like this:
name: 'ServiceName',

Resources