req.files showing undefined while uploading multiple files via multer - multer

I have initialized disk storage and multer in schema file as static method
const mongoose = require('mongoose');
const multer = require('multer');
const path = require('path');
const POSTS_PATH = path.join('/uploads/posts/photos');
const postSchema = new mongoose.Schema({
content: {
type: String,
required: true
},
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
// include the array of ids of all comments in this post schema itself
comments: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Comment'
}
],
likes: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Like'
}
],
photos:[
{
type: String,
}
]
},{
timestamps: true
});
let storage = multer.diskStorage({
destination: function(req,file,cb){
cb(null,path.join(__dirname, '..', POSTS_PATH));
},
filename: function(req,file,cb){
const filename = file.fieldname+'-'+Date.now();
cb(null,filename);
}
})
postSchema.statics.uploadedPhotos = multer({storage: storage}).array('file',7);
postSchema.statics.postsPath = POSTS_PATH;
const Post = mongoose.model('Post', postSchema);
module.exports = Post;
called this method in my controller file
Post.uploadedPhotos(req, res, function(err){
if (err) {console.log('*****Multer Error:******* ', err)};
console.log(req.files); // shows undefined..
});
This is my html form.
<form action="/posts/create" id="new-post-form" method="POST" enctype="multipart/form-data">
<textarea name="content" cols="30" rows="3" placeholder="Type Here..." required></textarea>
<input type="file" name="file" placeholder="Upload Photos" multiple>
<input type="submit" value="Post">
</form>
problem is when is call console.log for req.files in controller file it shows undefined
could you please rectify my mistake..
I have tried everything but still its shows undefined..

Related

Yup compare fields validation with react hook form

I've been using React hook form and have a compare validation written on the input itself.
I need to move over to Yup validation lib as others on the project are using it so for consistency. Here is what I currently have that is working but having problems when I use a yup.schema.
const {
register,
setValue,
getValues,
formState: { errors, isValid },
clearErrors,
trigger,
} = useForm({
mode: 'onBlur',
defaultValues: {
password: '',
compare: '',
},
})
return(
<div>
<Input
name='password'
{...register('password', { required: true })}
<Input
name='compare'
{...register('compare', {
validate: (value: string) => {
const { password} = getValues()
return password === value || ''
},
})}
</div>
)
As I said this above works but now I thought I could add a schema but that breaks all what I have so I'm trying to figure out how I can achieve this using yup schema.
const schema = yup.object().shape({
password: yup.string().required(),
compare: yup.string().test(
'compare',
(field) => {
... not sure how to compare against another filed here ?
}
),
})
const {
register,
setValue,
getValues,
formState: { errors, isValid },
clearErrors,
trigger,
} = useForm({
mode: 'onBlur',
resolver: yupResolver(schema),
defaultValues: {
password: '',
compare: '',
},
})

Cannot consume rest api (Web Api) from component React

I'm developing a web, it consume a rest api, this api rest is build in asp.net as a Web Api. My issue is present when try consume an endpoint, because use fetch, but this not show any.
this is my code
import React from 'react';
import BootstrapTable from 'react-bootstrap-table-next';
class BundleShipping extends React.Component {
constructor(props) {
super(props)
this.state = {
pickTicket: '',
Pallets: [],
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({ pickTicket: event.target.value });
}
handleSubmit(event) {
this.GetParametersPickTicket('016683O01', 'en-US', 'e3eda398-4f2a-491f-8c8e-e88f3e369a5c')
.then((responseData) => { this.setState({ Pallet: responseData.Data.Pallet }) })
.then((response) => console.log(response))
}
GetParametersPickTicket(PickTicket, language, Plant) {
console.log(PickTicket)
console.log(language)
console.log(Plant)
return fetch('http://localhost:55805/api/GicoBundleWA/GetParametersPickTicket', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
pickTicket_str: PickTicket,
kPlant: Plant,
language: language
}),
}).then((response) => response.json())
.then((responseJson) => { console.log(JSON.stringify(responseJson)) })
.catch((err) => console.log(err))
}
render() {
const columns = [{
dataField: 'PalletNumber',
text: 'Estibas Cargadas'
}, {
dataField: 'Quantity',
text: 'Cantidad'
}, {
dataField: 'Bundles',
text: 'Bultos'
}, {
dataField: 'Date_Time',
text: 'Fecha de carga'
}];
return (
<div className="container">
<form onSubmit={this.handleSubmit}>
<div className="col-lg-2 col-md-2 col-xs-3">
<label>Shipping</label>
</div>
<div className="form-group col-lg-5 col-md-5 col-xs-5">
<input type="text" value={this.state.pickTicket} onChange={this.handleChange} className="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter Pick Ticket" />
</div>
<button type="submit" className="btn btn-primary">Submit</button>
</form>
<BootstrapTable keyField='PalletNumber' data={this.state.Pallets} columns={columns} />
</div>
)
}
}
but onclick in the button not show data in console, only show it
016683O01 VM494 bundle.js:67423
en-US VM494 bundle.js:67424
e3eda398-4f2a-491f-8c8e-e88f3e369a5c VM494 bundle.js:67425
Navigated to http://localhost:3000/xxxx?
react-dom.development.js:17286 Download the React DevTools for a better development experience:
I did some tests for discover my error, for example execute code directly in console so:
function GetParametersPickTicket(PickTicket, language, Plant) {
console.log(PickTicket)
console.log(language)
console.log(Plant)
return fetch('http://localhost:xxx/api/XXX/YYYY', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
pickTicket_str: PickTicket,
kPlant: Plant,
language: language
}),
}).then((response) => response.json())
.then((responseJson) => { console.log(JSON.stringify(responseJson)) })
.catch((err) => console.log(err))
}
GetParametersPickTicket('016683O01', 'en-US', 'e3eda398-4f2a-491f-8c8e-e88f3e369a5c')
and this one if it shows my answer json.
Additionally, i resolved issue with cors, and try with postman and it show
access-control-allow-origin →*
I don't understand, why in component react does not show any result
First problem is that your method GetParametersPickTicket simply logs the received json, but it never returns it. So, the consumer of this method will simply receive an empty resolved promise. See my comment "This part was missing" in the following snippet:
GetParametersPickTicket(PickTicket, language, Plant) {
return fetch('http://localhost:55805/api/GicoBundleWA/GetParametersPickTicket', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
pickTicket_str: PickTicket,
kPlant: Plant,
language: language
}),
}).then((response) => response.json())
.then((responseJson) => {
console.log(JSON.stringify(responseJson)
return responseJson // <-- This part was missing
})
.catch((err) => console.log(err))
}
Second problem is that you're getting redirected when your form is submitted, am I right? Thus, you need prevent this default form behaviour by adding a event.preventDefault() in the beginning of your handleSubmit method:
handleSubmit(event) {
event.preventDefault()
// ... other code here
}

Error module build failed, parse error with UglifyJsPlugin in webpack

I'm having an error I can't find a solution to.
I have a new VueJS project that I'm running in docker. It works fine in dev mode, but fails when I try to build for prod. The error is included below, and seems to be with eslint. I've removed sections until it works, and narrowed it down to the UglifyJsPlugin, but I don't know why.
I know I can remove the Uglify process, but I don't want to -- I want to solve the problem!
Errors look like this:
ERROR in ./~/vue-html-loader!./~/vue-loader/lib/selector.js?type=template&index=0!./~/eslint-loader!./src/components/UserInput.vue
Module build failed: Error: Parse Error: <input class="form-control" type:"text" v-model="newTodoText" v-on:keyup.enter="createTodo" placeholder="New todo">
<span class="btn btn-primary input-group-addon" v-on:click="createTodo">
Add
</span>
</div>
<div class="btn-group" role="group" aria-label="Second group">
<button type="button" class="btn btn-danger" v-on:click="showClearModal">
Clear all
</button>
</div>
</div>
<hr>
<div id="clearModal" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
Are you sure you want do delete them all?
</div>
<div class="modal-body">
<p>This will permanently destroy all todos, do you really want to do this?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button class="btn btn-danger btn-ok" v-on:click="clearTodos">Delete</button>
</div>
</div>
</div>
</div>
at new HTMLParser (/code/node_modules/html-minifier/src/htmlparser.js:236:13)
at minify (/code/node_modules/html-minifier/src/htmlminifier.js:945:3)
at Object.exports.minify (/code/node_modules/html-minifier/src/htmlminifier.js:1294:10)
at Object.module.exports (/code/node_modules/vue-html-loader/index.js:85:26)
# ./src/components/UserInput.vue 4:19-173
My webpack config looks like this for BASE:
var path = require('path')
var config = require('../config')
var cssLoaders = require('./css-loaders')
var projectRoot = path.resolve(__dirname, '../')
var webpack = require('webpack')
module.exports = {
entry: {
app: './src/main.js'
},
output: {
path: config.build.assetsRoot,
publicPath: config.build.assetsPublicPath,
filename: '[name].js'
},
resolve: {
extensions: ['', '.js', '.vue'],
fallback: [path.join(__dirname, '../node_modules')],
alias: {
'src': path.resolve(__dirname, '../src'),
'assets': path.resolve(__dirname, '../src/assets'),
'components': path.resolve(__dirname, '../src/components')
}
},
resolveLoader: {
fallback: [path.join(__dirname, '../node_modules')]
},
module: {
preLoaders: [
{
test: /\.vue$/,
loader: 'eslint',
include: projectRoot,
exclude: /node_modules/
},
{
test: /\.js$/,
loader: 'eslint',
include: projectRoot,
exclude: /node_modules/
}
],
loaders: [
{
test: /\.vue$/,
loader: 'vue'
},
{
test: /\.js$/,
loader: 'babel',
include: projectRoot,
exclude: /node_modules/
},
{
test: /\.json$/,
loader: 'json'
},
{
test: /\.html$/,
loader: 'vue-html'
},
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'url-loader?limit=10000&mimetype=application/font-woff'
},
{
test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'file-loader'
},
{
test: /\.(png|jpe?g|gif|otf)(\?.*)?$/,
loader: 'url',
query: {
limit: 10000,
name: path.join(config.build.assetsSubDirectory, '[name].[hash:7].[ext]')
}
},
{
test: /\.css$/,
loaders: ['style-loader', 'css-loader']
}
]
},
vue: {
loaders: cssLoaders()
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
Tether: 'tether'
})
],
eslint: {
formatter: require('eslint-friendly-formatter')
}
}
and PROD
var path = require('path')
var config = require('../config')
var webpack = require('webpack')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var cssLoaders = require('./css-loaders')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = merge(baseWebpackConfig, {
devtool: config.build.productionSourceMap ? '#source-map' : false,
output: {
path: config.build.assetsRoot,
filename: path.join(config.build.assetsSubDirectory, '[name].[chunkhash].js'),
chunkFilename: path.join(config.build.assetsSubDirectory, '[id].[chunkhash].js')
},
vue: {
loaders: cssLoaders({
sourceMap: config.build.productionSourceMap,
extract: true
})
},
plugins: [
// http://vuejs.github.io/vue-loader/workflow/production.html
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production'),
API_HOST: JSON.stringify(config.prod.api_host)
}
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
sourceMap: true
}),
new webpack.optimize.OccurenceOrderPlugin(),
// extract css into its own file
new ExtractTextPlugin(path.join(config.build.assetsSubDirectory, '[name].[contenthash].css')),
// generate dist index.html with correct asset hash for caching.
// you can customize output by editing /index.html
// see https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: process.env.NODE_ENV === 'testing'
? 'index.html'
: config.build.index,
template: 'index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
}
})
]
})
What am I missing?!

Async file upload in MVC using kendoUpload

I am using file uploader with MVC.
Following is my code :
<div class="demo-section k-content">
<input name="files" id="files" type="file" />
</div>
<script>
$(document).ready(function () {
var data = JSON.stringify({
'ReportID': '#(Model.ReportID)',
});
$("#files").kendoUpload({
async: {
saveUrl: '#Url.Action("save", "UserPage")',
//removeUrl: "remove",
autoUpload: true,
contentType: "application/json; charset=utf-8",
dataType: "json",
data: data,
}//,
});
});
on ActionResult I am using following code :
string fileName = Path.GetFileName(files.FileName);
fileName = model.ReportID + "s" + Guid.NewGuid() + extension;
Everything is working fine except the value of model.ReportID its returning NULL every time.
I am missing something here?
Try something like that:
#(Html.Kendo().Upload()
.Name("uploadFiles")
.Async(a => a
.Save("Save", "Upload")
.Remove("Remove", "Upload")
.AutoUpload(true)
.SaveField("files")
//.Batch(true)
.RemoveField("fileNames")
)
.Multiple(true)
.ShowFileList(true)
.Events(events => events
.Error("onUploadError")
.Progress("onUploadProgress")
.Complete("onUploadComplete")
.Success("onUploadSuccess")
.Select("onUploadSelect")
.Upload("onUploadAdditionalData")
.Remove("onUploadRemove"))
)
inside the onUploadAdditionalData event you can pass parameters like:
function onUploadAdditionalData(e) {
e.data = { val1: val1, val2: val2 };
}
your controller action should look like this:
public ActionResult Save(IEnumerable<HttpPostedFileBase> files, string val1, string val2)
{
//do upload handling here
}
If you check documentation http://docs.telerik.com/kendo-ui/api/javascript/ui/upload#configuration-async async.data is undocumented and i am not sure if there is such property.
You can put it directly to saveUrl:
saveUrl: '#Url.Action("save", "UserPage", new { ReportID = Model.ReportID })'

Fetching ID from Select menu and saving record as one-to-many

I have been trying to fetch the id of this Select helper all day, and still noting but nil's and undefined...
I just want the product_id to be set to the value in the Select which is being set fine in the template....
// Models
Amber.Consumption = DS.Model.extend({
product: DS.belongsTo('product', {async: true}),
quantityUsed: DS.attr('number'),
location: DS.attr('string'),
employeeName: DS.attr('string'),
processed: DS.attr('boolean', {defaultValue: false})
});
Amber.Product = DS.Model.extend({
quantityStock: DS.attr('number'),
product: DS.attr('string'),
consumptions: DS.hasMany('consumption', {async:true})
});
/consumption/new.hbs
<form {{action "create" on="submit"}}>
<div>
<label>Produkt<br />
{{view "select"
content=products
selection=products
optionValuePath="content.id"
optionLabelPath="content.product"
}}
</label>
</div><br />
...
// controller
Amber.ConsumptionsNewController = Ember.ObjectController.extend ({
products: function() {
return this.store.find('product')
}.property('product')
});
// Route + routes
Amber.Router.map(function() {
this.resource('products', function() {
this.route('new');
this.route('update', { path: '/update/:product_id' });
this.route('show', { path: '/show/:product_id' });
this.resource('consumptions', function() {
this.route('new');
this.route('show', { path: '/show/:consumption_id' });
})
});
});
Amber.ConsumptionsNewRoute = Ember.Route.extend({
model: function() {
return this.store.createRecord('consumption', {
processed: true,
});
},
actions: {
create: function() {
var newConsumption = this.get('currentModel');
var self = this;
newConsumption.save().then(
function() { self.transitionTo('consumptions') },
function() { }
);
}
}
});
// Rails Serializers
class ConsumptionSerializer < ActiveModel::Serializer
attributes :id, :product_id, :quantity_used, :employee_name, :processed, :location
end
class ProductSerializer < ActiveModel::Serializer
attributes :id, :quantity_stock, :product
end
All the other values are being saved alright... but product_id is never set. Very frustrating when I can actually see the ID being bound to the option value in the html:
<select id="ember983" class="ember-view ember-select">
<option id="ember996" class="ember-view" value="1">A-Product</option>
I hope someone can help.. Have been stuck here for waaayyy to long now :/

Resources