How to upload a file? - html

I have been trying to upload a simple image using adonisjs and the request.file() keeps on returning null.
I am pretty new to adonisjs and the documentation is not clear on what to do.
I am using a SQLite database.
This is my controller.
public async update({response, request}) {
let user = request.only(["userId","fullname","avatar"]);
const coverImage = request.file('avatar')
console.log(coverImage)
console.log(user)
if (!coverImage) {
return "Please upload File"
}
const imageName = new Date().getTime().toString()+ '.' + coverImage.subtype
await coverImage.moveAll(Application.publicPath('images'),{
name: imageName
})
user.avatar = `images/${imageName}`
await user.save()
return response.redirect(`/users/${user.userId}`)
}
This is my form that I am submitting the image with.
<form class="uk-grid-small" uk-grid method="post" action="{{ route('profiles.update', {id: user.id}) }}?_method=PUT">
<div class="uk-width-1-2#s">
<input class="uk-input" type="text" placeholder="Fullname" name="fullname">
</div>
<div class="uk-width-3-4#s">
<label>Upload user avatar</label>
<input type="file" multiple name="avatar" class="form-control">
</div>
<div class="uk-width-1-2#s">
<button class="uk-button uk-button-primary">Submit</button>
</div>
</form>
This is the route I am using
Route.resource('profiles', 'ProfilesController')

AdonisJS provides you a robust and performant API for dealing with file uploads. Not only can you process and store uploaded files locally, but you can also stream them directly to the cloud services like S3, Cloudinary, or Google cloud storage.
Accessing uploaded files
The bodyparser middleware registered inside the start/kernel.ts file automatically processes all the files for multipart/form-data requests.
You can access the files using the request.file method. The method accepts the field name and returns an instance of the File class, or null if no file was uploaded.
try this code
<form action="{{ route('posts.store') }}" method="POST" enctype="multipart/form-data">
<div class="row">
<div class="col">
<div class="custom-file">
<input type="file" class="custom-file-input" name="image_url" id="validatedCustomFile" required>
<label class="custom-file-label" for="validatedCustomFile">Choose file...</label>
<div class="invalid-feedback">Example invalid custom file feedback</div>
</div>
</div>
</div>
<button type="submit" class="btn btn-success mt-2">Submit</button>
</form>
controller
const postImage = request.file('image_url', {
size: '2mb',
extnames: ['jpg', 'png'],
})
let date_ob = new Date();
if (!postImage) {
return
}
if (!postImage.isValid) {
return postImage.errors
}
if (postImage) {
await postImage.move(Application.publicPath('postImage'), {
name: ("0" + date_ob.getDate()).slice(-2)+("0" + (date_ob.getMonth() + 1)).slice(-2)+date_ob.getFullYear()+date_ob.getHours()+date_ob.getMinutes()+date_ob.getSeconds()+date_ob.getMilliseconds()+'.'+postImage.extname,
overwrite: true, // overwrite in case of conflict
})
}

Related

Send form data to a pdfkit iframe document

I would like to retrieve the values of a form and send them to a pdfkit document generated in back end.
For the moment, I only have created a simple document by a "get" route :
router.get(
"/",
authCheck,
asyncHandler(async (req: express.Request, res: express.Response) => {
const doc = new PDFDocument();
let filename = "toto";
filename = encodeURIComponent(filename) + ".pdf";
res.setHeader(
"Content-disposition",
'attachment; filename="' + filename + '"'
);
res.setHeader("Content-type", "application/pdf");
const content = "contenu";
doc.y = 300;
doc.text(content, 50, 50);
doc.pipe(res);
doc.end();
})
);
Here is the code to retrieve the created document :
<iframe className="preview-pdf__container" src={pdfContent} />
How do I send my form data and get it back into the document? With a POST?
This is how I was able to get data from my form into my server then export it to different files with in my server using node.js if it helps. I am not entirely sure on how to get it back out of your server into an iframe though.
HTML:
<div class="wrapper">
<form action="/login" method="POST">
<label id="email-label">Email</label>
<div class="textarea" id="email">
<input type="email" name="email" id="authentactor-email" value="" required>
</div>
<label>Password</label>
<div class="textarea" id="password">
<input type="password" name="password" id="authentactor-password" value="" required>
</div>
<div id="button-wrapper">
<button type="submit" id="button">Login</button>
</div>
</form>
</div>
node.js
//Allows you to Export form data from index.js
app.post('/login');

How do I access the returned json data from my controller from my ASP.NET Core AJAX form?

In my ASP.NET Core 3.1 web application, I have created a very basic Ajax form that makes use of the Unobtrusive Ajax library. When the form us submitted a check is carried out to find if a record with the same name currently exists and if it does, return any records that match that name as a Json Result along with the outcome of the request.
<form asp-controller="Test" asp-action="Create" id="CreateForm"
data-ajax="true"
data-ajax-method="POST">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="md-form form-group">
<label asp-for="Name"></label>
<input type="text" asp-for="Name" />
</div>
<div class="md-form form-group">
<button type="submit" value="Save" class="btn btn-info">Save</button>
</div>
</form>
Here is the controller that handles this form when it's submitted.
[HttpPost]
public IActionResult Create(Test model)
{
if (ModelState.IsValid)
{
bool safetyCheck = _testService.GetTests().Any(x => x.Name == model.Name);
if (safetyCheck == true)
{
var something = _testService.GetTests()
.Where(x => x.Name == model.Name /*&& x.Active == model.Active*/)
.Select(x => new { x.Id, x.Name })
.ToList();
return Json(new { success = false, error = something });
}
else {
//Add Record
_testService.InsertTest(model);
return Json(new { success = true });
}
}
else {
return View();
}
}
As you can see, the model is passed in, the model state is checked for validity and then a check is carried out to find out if the name passed in from the model matches any currently existing record. If the check is true then I create an object that can be sent back to the view via JSON along with the success = false.
If the name doesn't exist then the record is simply created.
What I want to know is, once this JSON data is returned, how do I then use it in my view, for example. If I return a list of all the records with the same name as I do above, how would I show the user this information along with a message?
In short, you'd need to write a custom JS function to process the return data. To hook it up to the AJAX request completion you can specify it in data-ajax-complete attribute value on your form.
It will look approximately like this:
<form asp-controller="Test" asp-action="Create" id="CreateForm"
data-ajax="true"
data-ajax-method="POST"
data-ajax-complete="ajax_handler">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="md-form form-group">
<label asp-for="Name"></label>
<input type="text" asp-for="Name" />
</div>
<div class="md-form form-group">
<button type="submit" value="Save" class="btn btn-info">Save</button>
</div>
</form>
#section Scripts
{
...
<script>
ajax_handler = function (xhr) {
var data = xhr.responseJSON;
// Process returned data here
};
</script>
}

How can we send and receive data in same HTML form using angularjs with JSON schema?

Suppose this is the form:
<form name="inputForm">
<input type="text" name="ipname" ng-model="formData.name">
<input type="text" name="ipage" ng-model="formData.age">
<button ng-submit="formSubmit(formData)"></button>
</form>
How do we need to write JSON schema with name or ng-model to store it in db?
You can do something as follows. The only issue in your version was you were using ng-submit with button which should be used at form level.
var app = angular.module('test',[]);
app.controller('testController',function($scope){
$scope.formData = {}
$scope.formSubmit = function() {
// Form validations
console.log($scope.formData)
// Use formData JSON Object to send it to API using $http/$resource
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"></script>
<body ng-app="test" ng-controller="testController">
<form name="inputForm">
<input type="text" name="ipname" ng-model="formData.name">
<input type="text" name="ipage" ng-model="formData.age">
<button ng-click="formSubmit()">Submit</button>
</form>
</body>

Unable to push data into JSON file AngularJS

i have just started learning Angular js. I find difficulty in adding the data to an existing JSON file.
This is my JSON file
{"response":[ {
"Cust_Fname":"Jack",
"Cust_Lname":"Nicolson",
"Cust_Dob":"24/09/1992",
"Cust_Mob":"0987654321",
"Cust_Email":"abc#xyz.com"
},
{
"Cust_Fname":"tom",
"Cust_Lname":"cruise",
"Cust_Dob":"19/01/1990",
"Cust_Mob":"1234567890",
"Cust_Email":"sss#gmail.com",
}
]
}
This is my AngularJS code to push data
$scope.saveContact = function(contact){
$http.post('/data/Cust_Dtls.json',contact).success(function(data, status, headers, config){
console.log(data)});
}
This is my HTML file
<ion-content class="item-noborder base-bg" overflow-scroll="true" padding="true">
<div class="row" >
<div class="col-50 pane-top-padding-20" style="padding-left:10px"><a class="button button-icon button-positive ion-arrow-left-c" href="#/tab/contacts"> Back to Contacts</a></div>
<div class="col-50 pane-top-padding-20 text-right"><a class="button button-icon button-positive ion-checkmark text-right" href="#/tab/contacts" ng-click="saveContact(contact)"> Save</a></div>
</div>
<div id="contact-div">
<label class="item">
<span class="input-label">First Name</span>
<input type="text" placeholder="First Name" ng-model="contact.Cust_Fname">
</label>
<label class="item">
<span class="input-label">Last Name</span>
<input type="text" placeholder="Last Name" ng-model="contact.Cust_Lname">
</label>
<label class="item">
<span class="input-label">Email</span>
<input type="text" placeholder="Email" ng-model="contact.Cust_Email">
</label>
<label class="item">
<span class="input-label">Phone</span>
<input type="text" placeholder="Phone" ng-model="contact.Cust_Mob">
</label>
<label class="item">
<span class="input-label">Date Of Birth</span>
<input type="text" placeholder="DOB" ng-model="contact.Cust_Dob">
</label>
</div>
</ion-content>
I am able to read the data using $http.get but i am unable to push data and i don't have any errors popping up. so i am unable to figure on what to do.
Thanks
I think you mean the post verb of http instead of push
The format is taken from angular site:
// Simple POST request example (passing data) :
$http.post('/someUrl', {msg:'hello word!'}).
success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
So taking your code you need to push contact like this:
$http.post('/data/Cust_Dtls',{contact:contact}).success(function(data, status, headers, config){
console.log(data)});
}
You need to post to a url instead of a json flat file.
You are doing same mistake I was doing. you trying to post data into local file using $http service.You cannot do this. $http service is for server-client communication. Use either localstorage or sqlite like services.
Hope this helps

Changing form type to multipart/form-data causes req.body to be empty

When I set up my form without specifying an enctype, Firefox automatically sets it to application/x-www-form-urlencoded and req.body contains a nice, JSON representation of all the parameters entered into the form. But when I change the enctype to multipart/form-data req.body is suddenly empty.
This is my form:
<form action="/create" method="post" enctype="multipart/form-data">
<fieldset>
<div>
<label>Category:</label>
</div>
<div>
<select name="category">
<option value="standard">Standard</option>
<option value="custom">Custom</option>
</div>
<div>
<input type="text" name="description">
</div>
<div>
<label>User ID:</label>
</div>
<div>
<input type="text" name="userid">
</div>
<div>
<input type="submit" value="Go">
</div>
</fieldset>
</form>
Doing a console.log(JSON.stringify(req.body, null, 2)); prints out an empty object when enctype is multipart/form-data and when enctype is not specified, it prints out something like:
{
category: "standard",
userid: "foo"
}
Any reason this is happening?
Try use busboy-body-parser to retrieve the request body parameters and the files.
start.js
var bodyParser = require('body-parser');
var busboyBodyParser = require('busboy-body-parser');
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({
extended: true
}));
// parse application/json
app.use(bodyParser.json());
//parse multipart/form-data
app.use(busboyBodyParser());
controllers/someController.js
someAction: function(req,res){
if(req.method == "POST"){
res.end(JSON.stringify(req.body)+JSON.stringify(req.files));
}
}
//{"text":"testx"}{"anexo":{"data":{"type":"Buffer","data":.... }}}
//req.body = {"text":"testx"}
//req.files = {"anexo":{"data":{"type":"Buffer","data":.... }}}
views/someController/someAction.html
<form method="post" id="multipart" enctype="multipart/form-data">
<input type="text" id="text1" name="text" value="testx" />
<input type="file" id="anexo" name="anexo" />
<input type="submit" value="Enviar" />
</form>
To create a file uploaded, you need work if the stream, for example:
/* file props
{
"data":{"type":"Buffer","data":.... },
"fieldname":"anexo",
"originalname":"images (1).jpg",
"encoding":"7bit",
"mimetype":"image/jpeg",
"destination":"c:\\live\\sources\\uploads\\",
"filename":"eventclock_images (1)_1443706175833.jpg",
"path":"c:\\live\\sources\\uploads\\eventclock_images(1)_1443706175833.jpg",
"size":9986
}
*/
var fileStream = fs.createWriteStream(file.path);
fileStream.write(file.data);
fileStream.end();
fileStream.on('error', function (err) {
//console.log("error",err);
});
fileStream.on('finish', function (res) {
//console.log("finish",res);
});
Sounds like you're using express.urlencoded() instead of express.multipart().
I think #robertklep is correct, but I disagree with his answer. express.multipart() is deprecated and should not be used.
If you need multipart form processing, I highly recommend Busboy. If you want all the details, see this answer.
npm install multer --save
in main.js
var multer = require('multer');
var upload = multer()
router.route("/quotes").post(upload.array(),function(req, res, next){
name = req.body.name;
email = req.body.email;
}