I Have uploaded my image in local folder using angular file-model and returning the path using json but i am unable to save the path to database. Please help me to solve this issue. I am using .success method to return the response data to a hidden field to store it in database but it shows ERROR:" Cannot read property 'success' of undefined ".
services.js:
service.UploadFile = function (file) {
var fd = new FormData();
fd.append('file', file);
$http.post('/Empdet/UploadFile', fd, {
transformRequest: angular.identity,
headers: { 'Content-Type': undefined }
})
.success(function () {
})
.error(function () {
});
}
return service;
Controller.js:
$scope.UploadFile = function () {
console.log('UploadFile');
console.log($scope.Empdet.PhotoFile);
EmployeeFactory.UploadFile($scope.Empdet.PhotoFile).success(function (response) {
console.log('response.IsSuccessful');
console.log(response.Data);
$scope.IsSuccessful = response.IsSuccessful;
if ($scope.IsSuccessful) {
$scope.PhotoText = response.Data;
console.log('$scope.PhotoText');
console.log($scope.PhotoText);
$scope.CanClearMessage = true;
} else {
$scope.SuccessMessage = '';
$scope.ErrorMessage = response.ReasonForFailure;
$scope.CanClearMessage = true;
}
}
)};
CreateNewEmployee.cshtml:
<tr>
<td style="text-align: left;">
<label class="labelsytle">
PhotoFile
</label>
</td>
<td style="text-align: left;">
<input class="form-control" type="file" file-model="Empdet.PhotoFile" style="border-radius: 5px;"/>
<td><button class="btn btn-primary" ng-click="UploadFile()" style="border-radius: 5px; font-family: Consolas;">UPLOAD</button></td>
</td>
</tr>
<tr>
#*<td style="text-align: left;">
<label class="labelsytle">
PhotoText
</label>
</td>*#
<td style="text-align: left;">
<input class="form-control" type="hidden" name="search" ng-model="Empdet.PhotoText" placeholder="Enter PhotoText" style="border-radius: 5px;" />
</td>
</tr>
EmpdetController.cs:
[HttpPost]
public ActionResult UploadFile()
{
var file = Request.Files[0];
var path = Path.Combine(Server.MapPath("~/Photos/") + file.FileName);
file.SaveAs(path);
// prepare a relative path to be stored in the database and used to display later on.
path = Url.Content(Path.Combine("~/Photos/" + file.FileName));
// save to db
return Json(path.ToString(), JsonRequestBehavior.AllowGet);
}
Use .then function instead of .success
Replace your .success and .error code block with below code
.then(function (d) {
//Success callback
}, function (error) {
//Failed Callback
alert('Error!');
});
Related
I want to send multiple records in the database using javascript in asp.net mvc i tried many different ways but all in vain. here I have the best code which can send the data to the controller but the file is not sending.
I search different ways i have found one is with FormData but i am unable to handle that in this context.
Controller:
public ActionResult SaveAllFeedback(FEEDBACKVM[] fEEDBACKs)
{
try
{
if (fEEDBACKs != null)
{
FEEDBACK fEEDBACK = new FEEDBACK();
foreach (var item in fEEDBACKs)
{
fEEDBACK.DATE = item.DATE;
fEEDBACK.COMMENT = item.COMMENT;
fEEDBACK.STUDENTID = item.STUDENTID;
fEEDBACK.TEACHERID = db.TEACHERs.Where(x => x.EMAIL == User.Identity.Name).FirstOrDefault().ID;
if (item.HOMEWORK != null)
{
fEEDBACK.HOMEWORK = SaveToPhysicalLocation(item.HOMEWORK);
}
db.FEEDBACKs.Add(fEEDBACK);
}
db.SaveChanges();
return Json("Done", JsonRequestBehavior.AllowGet);
}
return Json("Unable to save your feedback! Please Provice correct information", JsonRequestBehavior.AllowGet);
}
catch (Exception)
{
return Json("Unable to save your feedback! Please try again later.", JsonRequestBehavior.AllowGet);
}
}
ViewPage:
<form>
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<input name="DATE" id="DATE" type="date" class="form-control" />
</div>
<table class="table table-responsive table-hover" id="table1">
<thead>
<tr class="bg-cyan">
<th></th>
<th>RollNumber</th>
<th>Comment</th>
<th>Homework</th>
</tr>
</thead>
<tbody>
#foreach (var item in ViewBag.students)
{
<tr>
<td>
<input name="STUDENTID" type="text" value="#item.Key" hidden="hidden" />
</td>
<td>
<input name="STUDENTROLLNUMBER" type="text" value="#item.Value" class="form-control" readonly="readonly" />
</td>
<td>
<input name="COMMENT" type="text" class="form-control" />
</td>
<td>
<input name="HOMEWORK" type="file" class="form-control" />
</td>
</tr>
}
</tbody>
</table>
<div class="form-group">
<div class="col-md-10">
#Html.ValidationMessage("ErrorInfo", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button id="saveButton" type="submit" class="btn btn-danger">Save Attendance</button>
</div>
</div>
</form>
Script:
<script>
//After Click Save Button Pass All Data View To Controller For Save Database
function saveButton(data) {
return $.ajax({
contentType: 'application/json; charset=utf-8',
dataType: 'json',
type: 'POST',
url: '#Url.Action("SaveAllFeedback", "Teacherss")',
data: data,
success: function (result) {
alert(result);
location.reload();
},
error: function () {
alert("Error!")
}
});
}
//Collect Multiple Order List For Pass To Controller
$("#saveButton").click(function (e) {
e.preventDefault();
var formData = new FormData();
var arr = [];
arr.length = 0;
$.each($("#table1 tbody tr"), function () {
//arr.push({
// //DATE: $("#DATE").val(),
// //STUDENTID: $(this).find('td:eq(0) input').val(),
// //COMMENT: $(this).find('td:eq(2) input').val(),
// //HOMEWORK: $(this).find('td:eq(3) input').val()
// });
formData.append("DATE", $("#DATE").val());
formData.append("STUDENTID", $(this).find('td:eq(0) input').val());
formData.append("COMMENT", $(this).find('td:eq(2) input').val());
formData.append("HOMEWORK", $(this).find('td:eq(3) input')[0].files[0]);
});
var data = JSON.stringify({
fEEDBACKs: formData
});
$.when(saveButton (data)).then(function (response) {
console.log(response);
}).fail(function (err) {
console.log(err);
});
});
</script>
I just want to send multiple records with the file to the database
are you sure you want send the files???? if yes then
Your form tag should be look like this
<form id="yourid" action="youraction" enctype="multipart/form-data">
Form Component
</form>
NOTE:- enctype="multipart/form-data" tag is important
and then controller should be look like this
public ActionResult YourController(FormCollection data)
{
if (Request.Files.Count > 0)
{
foreach (string fileName in Request.Files)
{
HttpPostedFileBase file = Request.Files[fileName];
//you can save the file like this
string path = Server.MapPath("~/Yourpath/FileName" + fileName.Substring(fileName.LastIndexOf('.')));
file.SaveAs(path);
//or you can load it to memory like this
MemoryStream ms = new MemoryStream();
file.InputStream.CopyTo(ms);
//use it how you like
}
}
return View();
}
When the below form is submitted, and additional entry is created into the database. But the ng-repeat is not getting refreshed.
Any ideas?
html code:
<table class="redTable">
<thead>
<tr>
<th> Domain</th>
<th> Username</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="eachuserconfigdata in userconfigdata track by $index">
<td>
<input type="text" ng-model="eachuserconfigdata.Domain" value="{{ eachuserconfigdata.Domain }}" ng-readonly='!($index == eEditable)' ng-dblclick="eEditable = $index" style="background-color: transparent ; width:80px;border: 0;" />
</td>
<td>
<input type="text" ng-model="eachuserconfigdata.UserName" value="{{ eachuserconfigdata.UserName }}" ng-readonly='!($index == eEditable)' ng-dblclick="eEditable = $index" style="background-color: transparent ; width:80px;border: 0;" />
</td>
</tr>
</tbody>
</table>
<br />
</div>
Javascript
var myApp = angular.module("mymodule", ['ngMaterial']);
var myController = function ($scope, $http, $log) {
$scope.username = "";
$scope.ps = "";
$scope.submit = function () {
//alert($scope.username);
//alert($scope.ps);
$scope.myStyle = { color: 'red' };
var data = {
Domain: $scope.domainname,
UserName: $scope.domainusername,
Password: $scope.domainps
};
$http({
method: 'POST',
//url: 'Login/LoginUser?user=' + $scope.username + '&password=' + $scope.ps,
url: 'Login/UpdateDomainConfiguration',
data: data,
headers: { "Content-Type": "application/json" }
})
.then(function successCallback(response) {
var userid = 0;
$scope.message = response.data;
//$log.info(response);
$scope.GetUserConfigDetails();
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
alert(response.data);
});
}
What you did based on your code is you just saved it to db but never fetched it (not sure about this $scope.GetUserConfigDetails(); though).
What you need to do is after saving it to db, fetch the data again and assign it to your ng-repeat array. Or you can just simply insert the data you've saved to the db into your existing array so that you don't have to fetch again.
Currently I am working on WCF project. I am consuming my wcf project into Angular JS Application but when I run the application it does not provide any error. There are errors when I launch developer tools in Google Chrome and I cannot insert, update and delete etc. It's showing following errors...... Anyone help me to correct this errors I would be grateful.
?o=3&g=EC0825C4-90A4-2692-D257-CD2C2B565912&s=1A2C77E8-0498-4A11-B8B8-D740DBEC71C4&z=1403834305:2 Uncaught SyntaxError: Unexpected token <
2angular.js:12701 OPTIONS http://localhost:50028/StudentService.svc/AddNewStudent 405 (Method Not Allowed)
Index:1 XMLHttpRequest cannot load http://localhost:50028/StudentService.svc/AddNewStudent. Response for preflight has invalid HTTP status code 405
Modules.js:52 Some error Occured[object Object]
Index:1 GET http://localhost:50028/StudentService.svc/GetAllStudent/ 400 (Bad Request)
angular.js:14642 ReferenceError: $log is not defined
at Modules.js:18
at angular.js:17000
at m.$digest (angular.js:18182)
at m.$apply (angular.js:18480)
at l (angular.js:12501)
at XMLHttpRequest.s.onload (angular.js:12655) "Possibly unhandled rejection: {}"
Her is code in Angular JS ...
/// <reference path="../angular.min.js" />
var app;
(function () {
app = angular.module("RESTClientModule", []);
app.controller("CRUD_AngularJs_RESTController", function ($scope, CRUD_AngularJs_RESTService) {
$scope.OperType = 1;
//1 Mean New Entry
GetAllRecords();
//To Get All Records
function GetAllRecords() {
var promiseGet = CRUD_AngularJs_RESTService.getAllStudent();
promiseGet.then(function (pl) { $scope.Students = pl.data },
function (errorPl) {
$log.error('Some Error in Getting Records.', errorPl);
});
}
//To Clear all input controls.
function ClearModels() {
$scope.OperType = 1;
$scope.StudentID = "";
$scope.Name = "";
$scope.Email = "";
$scope.Class = "";
$scope.EnrollYear = "";
$scope.City = "";
$scope.Country = "";
}
//To Create new record and Edit an existing Record.
$scope.save = function () {
var Student = {
Name: $scope.Name,
Email: $scope.Email,
Class: $scope.Class,
EnrollYear: $scope.EnrollYear,
City: $scope.City,
Country: $scope.Country
};
if ($scope.OperType === 1) {
var promisePost = CRUD_AngularJs_RESTService.post(Student);
promisePost.then(function (pl) {
$scope.StudentID = pl.data.StudentID;
GetAllRecords();
ClearModels();
}, function (err) {
console.log("Some error Occured" + err);
});
} else {
//Edit the record
debugger;
Student.StudentID = $scope.StudentID;
var promisePut = CRUD_AngularJs_RESTService.put($scope.StudentID, Student);
promisePut.then(function (pl) {
$scope.Message = "Student Updated Successfuly";
GetAllRecords();
ClearModels();
}, function (err) {
console.log("Some Error Occured." + err);
});
}
};
//To Get Student Detail on the Base of Student ID
$scope.get = function (Student) {
var promiseGetSingle = CRUD_AngularJs_RESTService.get(Student.StudentID);
promiseGetSingle.then(function (pl) {
var res = pl.data;
$scope.StudentID = res.StudentID;
$scope.Name = res.Name;
$scope.Email = res.Email;
$scope.Class = res.Class;
$scope.EnrollYear = res.EnrollYear;
$scope.City = res.City;
$scope.Country = res.Country;
$scope.OperType = 0;
},
function (errorPl) {
console.log('Some Error in Getting Details', errorPl);
});
}
//To Delete Record
$scope.delete = function (Student) {
var promiseDelete = CRUD_AngularJs_RESTService.delete(Student.StudentID);
promiseDelete.then(function (pl) {
$scope.Message = "Student Deleted Successfuly";
GetAllRecords();
ClearModels();
}, function (err) {
console.log("Some Error Occured." + err);
});
}
});
app.service("CRUD_AngularJs_RESTService", function ($http) {
//Create new record
this.post = function (Student) {
var request = $http({
method: "post",
url: "http://localhost:50028/StudentService.svc/AddNewStudent",
data: Student
});
return request;
}
//Update the Record
this.put = function (StudentID, Student) {
debugger;
var request = $http({
method: "put",
url: "http://localhost:50028/StudentService.svc/UpdateStudent",
data: Student
});
return request;
}
this.getAllStudent = function () {
return $http.get("http://localhost:50028/StudentService.svc/GetAllStudent");
};
//Get Single Records
this.get = function (StudentID) {
return $http.get("http://localhost:50028/StudentService.svc/GetStudentDetails/" + StudentID);
}
//Delete the Record
this.delete = function (StudentID) {
var request = $http({
method: "delete",
url: "http://localhost:50028/StudentService.svc/DeleteStudent/" + StudentID
});
return request;
}
});
})();
Here is the WCF service Code ......
[ServiceContract]
public interface IStudentService
{
[OperationContract]
[WebInvoke(Method = "GET",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/GetAllStudent/")]
List<StudentDataContract> GetAllStudent();
[OperationContract]
[WebGet(RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/GetStudentDetails/{StudentId}")]
StudentDataContract GetStudentDetails(string StudentId);
[OperationContract]
[WebInvoke(Method = "POST",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/AddNewStudent")]
bool AddNewStudent(StudentDataContract student);
[OperationContract]
[WebInvoke(Method = "PUT",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/UpdateStudent")]
void UpdateStudent(StudentDataContract contact);
[OperationContract]
[WebInvoke(Method = "DELETE",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "DeleteStudent/{StudentId}")]
void DeleteStudent(string StudentId);
}
}
Here is Implementation of method of wcf service
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace WCF_REST_Service
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "StudentService" in code, svc and config file together.
// NOTE: In order to launch WCF Test Client for testing this service, please select StudentService.svc or StudentService.svc.cs at the Solution Explorer and start debugging.
public class StudentService : IStudentService
{
StudentManagementEntities ctx;
public StudentService()
{
ctx = new StudentManagementEntities();
}
public List<StudentDataContract> GetAllStudent()
{
var query = (from a in ctx.Students
select a).Distinct();
List<StudentDataContract> studentList = new List<StudentDataContract>();
query.ToList().ForEach(rec =>
{
studentList.Add(new StudentDataContract
{
StudentID = Convert.ToString(rec.StudentID),
Name = rec.Name,
Email = rec.Email,
EnrollYear = rec.EnrollYear,
Class = rec.Class,
City = rec.City,
Country = rec.Country
});
});
return studentList;
}
public StudentDataContract GetStudentDetails(string StudentId)
{
StudentDataContract student = new StudentDataContract();
try
{
int Emp_ID = Convert.ToInt32(StudentId);
var query = (from a in ctx.Students
where a.StudentID.Equals(Emp_ID)
select a).Distinct().FirstOrDefault();
student.StudentID = Convert.ToString(query.StudentID);
student.Name = query.Name;
student.Email = query.Email;
student.EnrollYear = query.EnrollYear;
student.Class = query.Class;
student.City = query.City;
student.Country = query.Country;
}
catch (Exception ex)
{
throw new FaultException<string>
(ex.Message);
}
return student;
}
public bool AddNewStudent(StudentDataContract student)
{
try
{
Student std = ctx.Students.Create();
std.Name = student.Name;
std.Email = student.Email;
std.Class = student.Class;
std.EnrollYear = student.EnrollYear;
std.City = student.City;
std.Country = student.Country;
ctx.Students.Add(std);
ctx.SaveChanges();
}
catch (Exception ex)
{
throw new FaultException<string>
(ex.Message);
}
return true;
}
public void UpdateStudent(StudentDataContract student)
{
try
{
int Stud_Id = Convert.ToInt32(student.StudentID);
Student std = ctx.Students.Where(rec => rec.StudentID == Stud_Id).FirstOrDefault();
std.Name = student.Name;
std.Email = student.Email;
std.Class = student.Class;
std.EnrollYear = student.EnrollYear;
std.City = student.City;
std.Country = student.Country;
ctx.SaveChanges();
}
catch (Exception ex)
{
throw new FaultException<string>
(ex.Message);
}
}
public void DeleteStudent(string StudentId)
{
try
{
int Stud_Id = Convert.ToInt32(StudentId);
Student std = ctx.Students.Where(rec => rec.StudentID == Stud_Id).FirstOrDefault();
ctx.Students.Remove(std);
ctx.SaveChanges();
}
catch (Exception ex)
{
throw new FaultException<string>
(ex.Message);
}
}
}
}
Here is HTML CODE ...
#{
Layout = null;
}
<!DOCTYPE html>
<html data-ng-app="RESTClientModule">
<head title="ASAS">
<title></title>
<script src="~/Scripts/angular.min.js"></script>
<script src="~/Scripts/MyScripts/Modules.js"></script>
</head>
<body>
<table id="tblContainer" data-ng-controller="CRUD_AngularJs_RESTController">
<tr>
<td>
<table style="border: solid 2px Green; padding: 5px;">
<tr style="height: 30px; background-color: skyblue; color: maroon;">
<th></th>
<th>ID</th>
<th>Name</th>
<th>Email</th>
<th>Class</th>
<th>Year</th>
<th>City</th>
<th>Country</th>
<th></th>
<th></th>
</tr>
<tbody data-ng-repeat="stud in Students">
<tr>
<td></td>
<td><span>{{stud.StudentID}}</span></td>
<td><span>{{stud.Name}}</span></td>
<td><span>{{stud.Email}}</span></td>
<td><span>{{stud.Class}}</span></td>
<td><span>{{stud.EnrollYear}}</span></td>
<td><span>{{stud.City}}</span></td>
<td><span>{{stud.Country}}</span></td>
<td>
<input type="button" id="Edit" value="Edit" data-ng-click="get(stud)" />
</td>
<td>
<input type="button" id="Delete" value="Delete" data-ng-click="delete(stud)" />
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td>
<div style="color: red;">{{Message}}</div>
<table style="border: solid 4px Red; padding: 2px;">
<tr>
<td></td>
<td>
<span>Student ID</span>
</td>
<td>
<input type="text" id="StudentID" readonly="readonly" data-ng-model="StudentID" />
</td>
</tr>
<tr>
<td></td>
<td>
<span>Student Name</span>
</td>
<td>
<input type="text" id="sName" required data-ng-model="Name" />
</td>
</tr>
<tr>
<td></td>
<td>
<span>Email</span>
</td>
<td>
<input type="text" id="sEmail" required data-ng-model="Email" />
</td>
</tr>
<tr>
<td></td>
<td>
<span>Class</span>
</td>
<td>
<input type="text" id="sClass" required data-ng-model="Class" />
</td>
</tr>
<tr>
<td></td>
<td>
<span>Enrollement Year</span>
</td>
<td>
<input type="text" id="sEnrollYear" required data-ng-model="EnrollYear" />
</td>
</tr>
<tr>
<td></td>
<td>
<span>City</span>
</td>
<td>
<input type="text" id="sCity" required data-ng-model="City" />
</td>
</tr>
<tr>
<td></td>
<td>
<span>Country</span>
</td>
<td>
<input type="text" id="sCountry" required data-ng-model="Country" />
</td>
</tr>
<tr>
<td></td>
<td></td>
<td>
<input type="button" id="save" value="Save" data-ng-click="save()" />
<input type="button" id="Clear" value="Clear" data-ng-click="clear()" />
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
Here is screen shot when I run the application..
First, you need to use * in [ServiceContract]. like this:
[WebInvoke(Method = "*"
That way, you allow your method to receive OPTIONS requests.
Then you should add this to your web.config:
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*"/>
<add name="Access-Control-Allow-Headers" value="X-Requested-With,Content-Type, Accept" />
</customHeaders>
</httpProtocol>
Do not forgot to handle OPTIONS requests. Something like this will solve it:
public List<StudentDataContract> GetAllStudent()
{
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
return null;
var query = (from a in ctx.Students
select a).Distinct();
List<StudentDataContract> studentList = new List<StudentDataContract>();
query.ToList().ForEach(rec =>
{
studentList.Add(new StudentDataContract
{
StudentID = Convert.ToString(rec.StudentID),
Name = rec.Name,
Email = rec.Email,
EnrollYear = rec.EnrollYear,
Class = rec.Class,
City = rec.City,
Country = rec.Country
});
});
return studentList;
}
That's it. Good luck.
ANGULAR JS
var App = angular.module('myApp', [])
App.controller('mainController', function ($scope, $http) {
$http.get("/Project/getProjects")
.success(function (result) {
$scope.SuccMsg = "SUCCESS.. ";
$scope.projectList = result;
})
.error(function (Data) {
$scope.ErrMsg = "ERROR.. " + Error;
}) })
CONRTOLLER : PROJECT
public JsonResult getProjects()
{
List<Project> p2 = new List<Project>();
p2 = db.Projects.ToList();
return Json(p2,JsonRequestBehavior.AllowGet);
}
HTML FILE
Project
<div ng-controller="mainController">
#*LIST PROJECT*#
<table id="tbl_Project" class="table-striped">
<tr ng-repeat="item in projectList">
<td>{{item.p_name}}</td>
<td>#*DELETE PROJECT*#
<input id="btn_delete" ng-click="deleteProject(item)" value="X" type="button" />
</td>
</tr>
</table>
<br /><br />
<div style="color:firebrick"><b>{{ErrMsg}}</b></div>
<div style="color:forestgreen"><b>{{SuccMsg}}</b></div> </div>
I'm a beginner to angular.js but I have a good grasp of the basics.
What I am looking to do is upload a file and some form data as multipart form data. I read that this isn't a feature of angular, however 3rd party libraries can get this done. I've cloned angular-file-upload via git, however I am still unable to post a simple form and a file.
Can someone please provide an example, html and js of how to do this?
First of all
You don't need any special changes in the structure. I mean: html input tags.
<input accept="image/*" name="file" ng-value="fileToUpload"
value="{{fileToUpload}}" file-model="fileToUpload"
set-file-data="fileToUpload = value;"
type="file" id="my_file" />
1.2 create own directive,
.directive("fileModel",function() {
return {
restrict: 'EA',
scope: {
setFileData: "&"
},
link: function(scope, ele, attrs) {
ele.on('change', function() {
scope.$apply(function() {
var val = ele[0].files[0];
scope.setFileData({ value: val });
});
});
}
}
})
In module with $httpProvider add dependency like ( Accept, Content-Type etc) with multipart/form-data. (Suggestion would be, accept response in json format)
For e.g:
$httpProvider.defaults.headers.post['Accept'] = 'application/json, text/javascript';
$httpProvider.defaults.headers.post['Content-Type'] = 'multipart/form-data; charset=utf-8';
Then create separate function in controller to handle form submit call.
like for e.g below code:
In service function handle "responseType" param purposely so that server should not throw "byteerror".
transformRequest, to modify request format with attached identity.
withCredentials : false, for HTTP authentication information.
in controller:
// code this accordingly, so that your file object
// will be picked up in service call below.
fileUpload.uploadFileToUrl(file);
in service:
.service('fileUpload', ['$http', 'ajaxService',
function($http, ajaxService) {
this.uploadFileToUrl = function(data) {
var data = {}; //file object
var fd = new FormData();
fd.append('file', data.file);
$http.post("endpoint server path to whom sending file", fd, {
withCredentials: false,
headers: {
'Content-Type': undefined
},
transformRequest: angular.identity,
params: {
fd
},
responseType: "arraybuffer"
})
.then(function(response) {
var data = response.data;
var status = response.status;
console.log(data);
if (status == 200 || status == 202) //do whatever in success
else // handle error in else if needed
})
.catch(function(error) {
console.log(error.status);
// handle else calls
});
}
}
}])
<script src="//unpkg.com/angular/angular.js"></script>
This is pretty must just a copy of that projects demo page and shows uploading a single file on form submit with upload progress.
(function (angular) {
'use strict';
angular.module('uploadModule', [])
.controller('uploadCtrl', [
'$scope',
'$upload',
function ($scope, $upload) {
$scope.model = {};
$scope.selectedFile = [];
$scope.uploadProgress = 0;
$scope.uploadFile = function () {
var file = $scope.selectedFile[0];
$scope.upload = $upload.upload({
url: 'api/upload',
method: 'POST',
data: angular.toJson($scope.model),
file: file
}).progress(function (evt) {
$scope.uploadProgress = parseInt(100.0 * evt.loaded / evt.total, 10);
}).success(function (data) {
//do something
});
};
$scope.onFileSelect = function ($files) {
$scope.uploadProgress = 0;
$scope.selectedFile = $files;
};
}
])
.directive('progressBar', [
function () {
return {
link: function ($scope, el, attrs) {
$scope.$watch(attrs.progressBar, function (newValue) {
el.css('width', newValue.toString() + '%');
});
}
};
}
]);
}(angular));
HTML
<form ng-submit="uploadFile()">
<div class="row">
<div class="col-md-12">
<input type="text" ng-model="model.fileDescription" />
<input type="number" ng-model="model.rating" />
<input type="checkbox" ng-model="model.isAGoodFile" />
<input type="file" ng-file-select="onFileSelect($files)">
<div class="progress" style="margin-top: 20px;">
<div class="progress-bar" progress-bar="uploadProgress" role="progressbar">
<span ng-bind="uploadProgress"></span>
<span>%</span>
</div>
</div>
<button button type="submit" class="btn btn-default btn-lg">
<i class="fa fa-cloud-upload"></i>
<span>Upload File</span>
</button>
</div>
</div>
</form>
EDIT: Added passing a model up to the server in the file post.
The form data in the input elements would be sent in the data property of the post and be available as normal form values.
It is more efficient to send the files directly.
The base64 encoding of Content-Type: multipart/form-data adds an extra 33% overhead. If the server supports it, it is more efficient to send the files directly:
Doing Multiple $http.post Requests Directly from a FileList
$scope.upload = function(url, fileList) {
var config = {
headers: { 'Content-Type': undefined },
transformResponse: angular.identity
};
var promises = fileList.map(function(file) {
return $http.post(url, file, config);
});
return $q.all(promises);
};
When sending a POST with a File object, it is important to set 'Content-Type': undefined. The XHR send method will then detect the File object and automatically set the content type.
Working Demo of "select-ng-files" Directive that Works with ng-model1
The <input type=file> element does not by default work with the ng-model directive. It needs a custom directive:
angular.module("app",[]);
angular.module("app").directive("selectNgFiles", function() {
return {
require: "ngModel",
link: function postLink(scope,elem,attrs,ngModel) {
elem.on("change", function(e) {
var files = elem[0].files;
ngModel.$setViewValue(files);
})
}
}
});
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app">
<h1>AngularJS Input `type=file` Demo</h1>
<input type="file" select-ng-files ng-model="fileList" multiple>
<h2>Files</h2>
<div ng-repeat="file in fileList">
{{file.name}}
</div>
</body>
You can check out this method for sending image and form data altogether
<div class="form-group ml-5 mt-4" ng-app="myApp" ng-controller="myCtrl">
<label for="image_name">Image Name:</label>
<input type="text" placeholder="Image name" ng-model="fileName" class="form-control" required>
<br>
<br>
<input id="file_src" type="file" accept="image/jpeg" file-input="files" >
<br>
{{file_name}}
<img class="rounded mt-2 mb-2 " id="prvw_img" width="150" height="100" >
<hr>
<button class="btn btn-info" ng-click="uploadFile()">Upload</button>
<br>
<div ng-show = "IsVisible" class="alert alert-info w-100 shadow mt-2" role="alert">
<strong> {{response_msg}} </strong>
</div>
<div class="alert alert-danger " id="filealert"> <strong> File Size should be less than 4 MB </strong></div>
</div>
Angular JS Code
var app = angular.module("myApp", []);
app.directive("fileInput", function($parse){
return{
link: function($scope, element, attrs){
element.on("change", function(event){
var files = event.target.files;
$parse(attrs.fileInput).assign($scope, element[0].files);
$scope.$apply();
});
}
}
});
app.controller("myCtrl", function($scope, $http){
$scope.IsVisible = false;
$scope.uploadFile = function(){
var form_data = new FormData();
angular.forEach($scope.files, function(file){
form_data.append('file', file); //form file
form_data.append('file_Name',$scope.fileName); //form text data
});
$http.post('upload.php', form_data,
{
//'file_Name':$scope.file_name;
transformRequest: angular.identity,
headers: {'Content-Type': undefined,'Process-Data': false}
}).success(function(response){
$scope.IsVisible = $scope.IsVisible = true;
$scope.response_msg=response;
// alert(response);
// $scope.select();
});
}
});