Laravel file upload not working: Call to a member function getClientOriginalName() on string - axios

I am trying to upload a file from an input field. I have the following fields:
<tr>
<td>
<input id="item" class="form-control-file my-2 w-100" type="file">
</td>
<td>
<input id="remark" class="form-control my-2 w-100" type="text">
</td>
</tr>
Then my axios post:
self.$http.post('http://127.0.0.1:8000/api/item/new', {
batchcode: document.getElementById("batchcode_form").value, // is somewhere else in the code, works fine.
product_code: document.getElementById("item").files[0].name,
remark: document.getElementById("item"),
input_type: 'item'
}).then(function (response) {
if (response.data.status === 'success') {
// success
} else {
// failed
}
});
The headers are displaying the following data:
batchcode "batchcode i filled in"
input_type: "file"
product_code: "filenamewithoutpath.png"
remark: "remark i filled in"
Now I have the following code in my itemscontroller:
public function store(Request $request)
{
if ($request->product_code != "" && $request->remark != "") {
// create item
$item = new Item;
$item->batchcode = $request->batchcode;
$item->remarks = $request->remark;
if ($request->input_type === "file") {
// upload file
$file = $request->product_code;
$item->product_code = $file->getClientOriginalName();
$new_name = time().$file->getClientOriginalName();
$path = public_path() . '/uploads/';
$file->move($path, $new_name);
$item->product_code = '/uploads/' . $new_name;
} else {
$item->product_code = $request->product_code;
}
$item->save();
return response()->json([
'status' => 'success',
'data' => $item
]);
} else {
return response()->json([
'status' => 'error',
'data' => 'Not all data was given.'
]);
}
}
When I execute this I get the following error:
Call to a member function getClientOriginalName() on string
I get the correct filename, but the upload part isn't working. I can't figure out or find anything on google why it doesn't work.

You can use FormData. Example:
let payload = new FormData()
And then add the fields to the form you want to send :
payload.set('input_type', 'item')
If you are uploading images or files, you may want to use .append
payload.append('remark', imageFile);
And then you can use axios post method (You can amend it accordingly)
self.$http.post('http://127.0.0.1:8000/api/item/new', payload, {
headers: {'Content-Type': 'multipart/form-data' }
})
.then(function (response) {
//handle success
console.log(response);
})
.catch(function (response) {
//handle error
console.log(response);
});

Related

SharePoint bulk update of multiple list items

I am currently working with binding SharePoint list items using JQuery datatables and rest API with the following code from Microsoft samples. I want to extend the sample to include multiple selection of row items with check boxes so that I can then another method to update the selected items. Please let me if this is possible with any guidance
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://cdn.datatables.net/1.10.15/js/jquery.dataTables.js"></script>
<script src="https://momentjs.com/downloads/moment.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.15/css/jquery.dataTables.min.css" />
<table id="requests" class="display" cellspacing="0" width="100%">
<thead>
<tr>
<th>ID</th>
<th>Business unit</th>
<th>Category</th>
<th>Status</th>
<th>Due date</th>
<th>Assigned to</th>
</tr>
</thead>
</table>
<script>
// UMD
(function(factory) {
"use strict";
if (typeof define === 'function' && define.amd) {
// AMD
define(['jquery'], function ($) {
return factory( $, window, document );
});
}
else if (typeof exports === 'object') {
// CommonJS
module.exports = function (root, $) {
if (!root) {
root = window;
}
if (!$) {
$ = typeof window !== 'undefined' ?
require('jquery') :
require('jquery')( root );
}
return factory($, root, root.document);
};
}
else {
// Browser
factory(jQuery, window, document);
}
}
(function($, window, document) {
$.fn.dataTable.render.moment = function (from, to, locale) {
// Argument shifting
if (arguments.length === 1) {
locale = 'en';
to = from;
from = 'YYYY-MM-DD';
}
else if (arguments.length === 2) {
locale = 'en';
}
return function (d, type, row) {
var m = window.moment(d, from, locale, true);
// Order and type get a number value from Moment, everything else
// sees the rendered value
return m.format(type === 'sort' || type === 'type' ? 'x' : to);
};
};
}));
</script>
<script>
$(document).ready(function() {
$('#requests').DataTable({
'ajax': {
'url': "../_api/web/lists/getbytitle('IT Requests')/items?$select=ID,BusinessUnit,Category,Status,DueDate,AssignedTo/Title&$expand=AssignedTo/Title",
'headers': { 'Accept': 'application/json;odata=nometadata' },
'dataSrc': function(data) {
return data.value.map(function(item) {
return [
item.ID,
item.BusinessUnit,
item.Category,
item.Status,
new Date(item.DueDate),
item.AssignedTo.Title
];
});
}
},
columnDefs: [{
targets: 4,
render: $.fn.dataTable.render.moment('YYYY/MM/DD')
}]
});
});
</script>

Excel file reading in mvc5 using javascript function

The Excel sheet want to read while it upload on a button click in MVC5.The uploaded excel file name is passed into action using AJAX method.Here the file variable get null value in posted method.
Here how can pass selected file as HttpPostedFileBase in the below ajax method.
`
<input style="display:none" type="file" id="fileupload1" />
<button type="button" onclick='$("#fileupload1").click()'>UPLOAD FROM EXCEL</button>
<span style="display:none" id="spnName"></span>
$(function () {$("#fileupload1").change(function () {
$("#spnName").html($("#fileupload1").val().substring($("#fileupload1").val().lastIndexOf('\\') + 1));
var file = $("#spnName").html();
$.ajax({
url: "UploadExcelForContractStaff",
type: 'POST',
data: JSON.stringify({ file: file }),
dataType: 'json',
contentType: "application/json; charset=utf-8",
success: function (data) {
}
});
});
});`
[AcceptVerbs(HttpVerbs.Post)]
public string UploadExcelForContractStaff(HttpPostedFileBase uploadFile)
{
StringBuilder strValidations = new StringBuilder(string.Empty);
try
{
if (uploadFile.ContentLength > 0)
{
string filePath = Path.Combine(HttpContext.Server.MapPath("../Uploads"),
Path.GetFileName(uploadFile.FileName));
uploadFile.SaveAs(filePath);
DataSet ds = new DataSet();
//A 32-bit provider which enables the use of
string ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filePath + ";Extended Properties=Excel 12.0;";
using (OleDbConnection conn = new System.Data.OleDb.OleDbConnection(ConnectionString))
{
conn.Open();
using (DataTable dtExcelSchema = conn.GetSchema("Tables"))
{
string sheetName = dtExcelSchema.Rows[0]["TABLE_NAME"].ToString();
string query = "SELECT * FROM [" + sheetName + "]";
OleDbDataAdapter adapter = new OleDbDataAdapter(query, conn);
//DataSet ds = new DataSet();
adapter.Fill(ds, "Items");
if (ds.Tables.Count > 0)
{
if (ds.Tables[0].Rows.Count > 0)
{
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
//Now we can insert this data to database...
}
}
}
}
}
}
}
catch (Exception ex) { }
return "";
}
I got solution. changed code like
<form enctype="multipart/form-data" id="frmUplaodFileAdd">
#Html.AntiForgeryToken()
<input style="display:none" type="file" id="fileupload1" />
<button type="button" onclick='$("#fileupload1").click()'>UPLOAD FROM EXCEL</button>
<span style="display:none" id="spnName"></span>
</form>
$.ajax({
url: "UploadFile", //Server script to process data
type: 'POST',
async: false,
xhr: function () { // Custom XMLHttpRequest
var myXhr = $.ajaxSettings.xhr();
if (myXhr.upload) { // Check if upload property exists
myXhr.upload.addEventListener('progress',
progressHandlingFunction, false); // For handling the progress of the upload
}
return myXhr;
},
data: formData,
//Options to tell jQuery not to process data or worry about content-type.
cache: false,
contentType: false,
processData: false,
success: function (data) { }
});
[HttpPost]
public ActionResult UploadFile(HttpPostedFileBase file)
{return Json();
}

Best way to make a Backbone app with RESTful Slim Framework

I'm using this video-example (https://www.youtube.com/watch?v=FZSjvWtUxYk) in order to make an errors reporting app. The problem comes when in the View when it passes the object that comes from the REST-AJAX call, _.template says that errores is not defined.
Here is my code:
var Error = Backbone.Model.extend({
defaults: {
iderror: '',
title: '',
url: ''
},
idAttribute: 'iderror'
});
var Errores = Backbone.Collection.extend({
model: Error,
url: '/errores'
});
var ErrorList = Backbone.View.extend({
el: '.page',
render: function (eventName) {
var that = this;
var errores = new Errores();
errores.fetch({
success: function (errores) {
var template = _.template($('#error-list-template').html(),{errores: errores.models});
that.$el.html(template);
}
});
}
});
My Template code:
<script type="text/template" id="error-list-template">
Registrar Error
<hr/>
<table class="table striped">
<thead>
<tr>
<th>Id Error</th>
<th>Título</th>
<th>URL</th>
<th></th>
</tr>
</thead>
<tbody>
<%
_.each(errores, function(error) { %>
<tr>
<td><%= error.get('iderror') %></td>
<td><%= error.get('title') %></td>
<td><%= error.get('url') %></td>
<td>Editar</td>
</tr>
<% }); %>
</tbody>
</table>
</script>
My RESTful GET function made with SLIM Framework:
$app->get('/errores/', function () {
//echo "Hello, ";
$datos = array();
$db = NewADOConnection('mysqli');
$db->Connect("localhost", "root", "mypassword", "tt1r");
$sql = "SELECT * FROM tt1r.course";
$qry = $db->execute($sql);
/*while (!$qry->EOF) {
//print_r($qry->fields);
$datos = [$qry->iderror => ['title' => $qry->title, 'url' => $qry->url]];
$qry->MoveNext();
}*/
if($qry) {
foreach($qry as $re){
//return $re['ADM_ID'];
$datos[] = array("iderror" => $re['iderror'],"title" => $re['title'],"url" => $re['url']);
}
$db = null;
//echo json_encode($datos);
//echo '{"user": ' . json_encode($datos) . '}';
echo json_encode($datos);
}
});
I have to say that I do get the JSON array with the data from the RESTful function, but it doesn't show it.
Thank you for your help.
Best regards.
Rafa
I read the answer in a post made by RyanP13.
So the fixed View code is:
var ErrorList = Backbone.View.extend({
el: '.page',
render: function () {
var that = this;
var errores = new Errores();
errores.fetch({
success: function(errores, response, options){
var template = _.template($('#error-list-template').html());
that.$el.html(template({ errores: errores.toJSON()}));
}
});
}
});
The problem was that I did not had any reference from the Collection.
Hope this help you as well.
Best regards
Rafa

Fine Uploader in Form Doesn't Submit Model Data into Controller

I have 2 questions:
1.) I have placed the Fine Uploader in a form and now I'm wondering why I don't see the filled content of the entry fields in my controller. How I can solve that?
2.) How can I do field validations before the upload process fires?
I hope someone can help!
Here is my code:
Model:
public class UploadFileModel
{
[StringLength(100)]
[Display(Name = "* Title:")]
public string Title { get; set; }
[StringLength(300)]
[Display(Name = "Description:")]
public string Description { get; set; }
}
View:
#model mowee.Models.UploadFileModel
<link href="~/Scripts/fineuploader/fineuploader-3.5.0.css" rel="stylesheet" />
#using (Html.BeginForm("UploadFile", "Home", FormMethod.Post, new { id = "uploadForm", enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary()
<fieldset>
<legend>Video Upload</legend>
<ol>
<li>
#Html.LabelFor(m => m.Title)
#Html.TextBoxFor(m => m.Title, new { #Class = "action add", title = "Enter your video/movie title here." })
</li>
<li>
#Html.LabelFor(m => m.Description)
#Html.TextAreaFor(m => m.Description, new Dictionary<string, object> { { "rows", "3" } })
</li>
</ol>
<div id="bootstrapped-fine-uploader"></div>
<script src="~/Scripts/fineuploader/fineuploader-3.5.0.js"></script>
<script>
function createUploader() {
var uploader = new qq.FineUploader({
element: document.getElementById('bootstrapped-fine-uploader'),
multiple: false,
validation: {
sizeLimit: 2147483648 //2GB
},
request: {
endpoint: '/Home/UploadFile'
},
text: {
uploadButton: '<div><i class="icon-upload icon-white"></i>* Upload Video</div>'
},
template: '<div class="qq-uploader span12">' +
'<pre class="qq-upload-drop-area span12"><span>{dragZoneText}</span></pre>' +
'<div id="btnUpload" class="qq-upload-button btn btn-success" style="width: 33%;">{uploadButtonText}</div>' +
'<span class="qq-drop-processing"><span>{dropProcessingText}</span><span class="qq-drop-processing-spinner"></span></span>' +
'<ul class="qq-upload-list" style="margin-top: 10px; text-align: center;"></ul>' +
'</div>',
classes: {
success: 'alert alert-success',
fail: 'alert alert-error',
dropActive: "cssClassToAddToDropZoneOnEnter"
}
});
}
window.onload = createUploader;
</script>
</fieldset>
}
Controller:
[HttpPost]
[AllowAnonymous]
[AcceptVerbs(HttpVerbs.Post)]
public JsonResult UploadFile(string qqfile, UploadFileModel myModel)
{
if (ModelState.IsValid)
{
try
{
HttpPostedFileBase uploadFile = null;
uploadFile = Request.Files[0];
if (uploadFile != null && uploadFile.ContentLength > 0)
{
if (myModel.Title != null || myModel.Description != null)
{
**//but UploadFileModel is null. WHY??????? Anyone an idea what i did wrong???
//write data to DB**
}
}
else
{
ModelState.AddModelError("", "Please choose a video/movie.");
return Json(new { success = false, message = "Please choose a video/movie." }, "application/json");
}
}
catch (Exception ex)
{
ModelState.AddModelError("", "An error occured. Try again.");
mailUtils.SendBugMail(ex, this.HttpContext);
return Json(new { success = false, message = "An error occured during upload. Try again." }, "application/json");
}
return Json(new { success = true, VideoLink = #ViewBag.VideoLink, VideoTranscoded = #ViewBag.Transcoded }, "application/json");//"text/html");
}
return Json(new { success = false, message = "An error occured during upload. Try again." }, "application/json");
}
OK. I figured it out. The params can be set on callback 'onSubmit' with setParams like that:
callbacks: {
onSubmit: function (id, fileName, responseJSON) {
uploader.setParams({
idxTitle: $('#titleId').val(),
idxAuthor: $('#authorId').val(),
idxEmail: $('#emailId').val()
});
},
And it works fine!
Addressing your questions:
You should really have a look at the MVC4 example in the Fine Uploader server-side examples repository. Model your server-side code after this example, and you should be fine. I personally am not an MVC4 developer, but I know the example I have linked to works.
You can make use of onValidate and onValidateBatch callbacks to perform your own validation tasks. Please have a look at the callbacks documentation for more info.

How to read the values returned by the Json?

I have the following code in my view:
<% using (Ajax.BeginForm("JsonCreate", new AjaxOptions { OnComplete = "createCategoryComplete" }))
{ %><div id="createCategory">
<fieldset>
<legend>Add new category</legend>
<p>
<%=Html.TextBox("CategoryId")%>
<%=Html.TextBox("Test")%>
<label for="name">Name:</label>
<%= Html.TextBox("Name")%>
<%= Html.ValidationMessage("Name")%>
</p>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
</div>
In the controller the code is as follows:
[AcceptVerbs(HttpVerbs.Post)]
public JsonResult JsonCreate(string Name)
{
if (ModelState.IsValid)
{
try
{
//Return a json object to the javascript
return Json(new { CategoryId = 123, Test= "test successful" });
}
catch
{
#region Log errors about the exception
//Log error to administrator here
#endregion
}
}
//If we got this far, something failed, return an empty json object
return Json(new { /* Empty object */ });
}
What should be the code in the view for the following function to read the values returned by the Json and update the textboxes for CategoryId and Test?
function createCategoryComplete() {....???}
function createCategoryComplete(e) {
var obj = e.get_object();
alert(obj.CategoryId + ' ' + obj.Test);
}
Try this,
success: function(data) {
alert(data.CategoryId + " " + data.Test);
EDIT:
function createCategoryComplete(data)
{
document.getElementById("UrTxtBoxID").value = data.Test;
}