I'm trying to upload an image along with other types of data using web api, angular JS .
My POST employee API controller action is :
[ResponseType(typeof(Employee))]
public async Task<IHttpActionResult> PostEmployee(Employee employee)
{
byte[] data = new byte[employee.Image.ContentLength];
employee.Image.InputStream.Read(data, 0, employee.Image.ContentLength);
employee.Picture = data;
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Employees.Add(employee);
await db.SaveChangesAsync();
return CreatedAtRoute("DefaultApi", new { id = employee.ID }, employee);
}
The Service JavaScript is:
app.service('Service', function ($http) {
this.getEmployees = function () {
return $http.ger("/api/EmployeeApi");
}
this.post = function (Employee) {
var request = $http({
method: "post",
url: "/api/EmployeeApi/PostEmployee",
data: Employee,
headers: {
'Content-Type' : 'application/json'
}
});
return request;
};
});
The "AddEmployee " Controller which I'm using for posting employee to the server is
app.controller('AddEmployee', function ($scope, Service) {
$scope.ID = 1;
$scope.save = function () {
var Employee = {
ID: $scope.ID,
Name: $scope.Name,
Experience: $scope.Experience,
EmployerName: $scope.EmployerName,
Image:$scope.Image
};
var Post = Service.post(Employee);
Post.then(function (pl) {
alert("Student Saved Successfully.");
},
function (errorPl) {
$scope.error = 'failure loading Student', errorPl;
});
};
});
The "Image" attribute Is not being posted to the server . rather it's throwing null. Probably problem with binding . I'm not sure why the image attribute is not being bind to the model while other attributes can.
I would assume that you are using an input with a type of file in your html to get the file name. Angular does not handle the binding for these automatically, so even though the file you selected shows up in the browser, it doesn't update the model. There are a number of directives available to work around this shortcoming.
This answer covers it pretty thoroughly. ng-model for <input type="file"/>
Related
I want to input Id via post method and get data for that Id back from database. I'm currently getting an error "employeeID is not defined" in my controller code.
Controller code:
$scope.employeeID = '10';
function test() {
var getData = myService.getEmployee(employeeID);
getData.then(function (emp) {
$scope.employees2 = emp.data;
}, function () {
alert('Error in getting records');
});
}
test(employeeID);
Service code:
this.getEmployee = function (employeeID) {
var response = $http({
method: "post",
url: "Home/getEmployeeByNo",
params: {
id: JSON.stringify(employeeID)
}
});
return response;
}
HomeController code:
public JsonResult getEmployeeByNo(string EmpNo)
{
using (InsiteEntities dataContext = new InsiteEntities())
{
int no = Convert.ToInt32(EmpNo);
var employeeList = dataContext.Employee.Find(no);
return Json(employeeList, JsonRequestBehavior.AllowGet);
}
}
Change
From
var getData = myService.getEmployee(employeeID);
To
var getData = myService.getEmployee($scope.employeeID);
You should pass EmpNo parameter inspite of id parameter in params object, so that the URL will form like Home/getEmployeeByNo?EmpNo=123
this.getEmployee = function (employeeID) {
var response = $http({
method: "post",
url: "Home/getEmployeeByNo",
params: {
EmpNo: employeeID //changed to `EmpNo`
}
});
return response;
}
Also pass employeeID from $scope as describe in Sajeeth's answer like myService.getEmployee($scope.employeeID);
I think it is not a big problem but I can't find any solution for this. Using Angular I want to display item details from database. I have my server side code that is searching for ID and returning Json. Then in Angular controller I get the data, single record. But I can't display any informations about this. It only works when I use ng-repeat but that's not the case. There is no point to use ng-repeat when I have just one single record.
//
It shouldn't be something like this?
$scope.item = { name: 'jack', city: 'sydney' };
And in my view
{{item.name}}
But with my single record from database it's not working. Do you have any idea what is wrong here? Or maybe I'm missing something? Here is my code
ASP.NET MVC Controller:
public JsonResult GetGame(int id, string gameName)
{
var getById = GetGameById(id, gameName);
if (getById != null)
{
using (KeyGameContext dbx = new KeyGameContext())
{
dbx.Configuration.ProxyCreationEnabled = false;
var getGame = dbx.Games.Find(id);
return Json(getGame, JsonRequestBehavior.AllowGet);
}
}
else
{
return Json(null);
}
}
public Game GetGameById(int gid, string gName)
{
return db.Games.Find(gid);
}
AngularJS code:
$http({
url: '/Genre/GetGame',
params: {
id: $routeParams.id,
gameName: $routeParams.gameName
},
method: 'get'
}).then(function (data) {
$scope.getGame = data;
console.log(data);
});
And here is some informations about this record from the console
Yea this throws people off when they first start using $http. Try this
$http({
url: '/Genre/GetGame',
params: {
id: $routeParams.id,
gameName: $routeParams.gameName
},
method: 'get'
}).then(function (data) {
$scope.getGame = data.data;
console.log(data);
});
What gets passed into your "then" promise function is the response object, which contains information about the http request in addition to your data. The actual data object is stored at .data
So I usually write mine as
$http({
url: '/Genre/GetGame',
params: {
id: $routeParams.id,
gameName: $routeParams.gameName
},
method: 'get'
}).then(function (response) {
$scope.getGame = response.data;
console.log(data);
});
just replace your code
$scope.getGame = data;
to
$scope.getGame = data.data;
"Happy Coding"
I need some help to solve this problem. To add new record to my database I'm using AngularJS and ASP.NET MVC (without reloading the page). All is working fine, but the problem appears when I'm trying to upload also image with HTML input type="file". I'm using FormData (I think it is the best way to do this?) to upload image and for the rest model properties I'm using ng-model and so on. The funny thing is that when I'm trying to save just image, without any other data then my controller gets the file but when I will add also some properties for my record like Name, Year, Author + image then the controller with only get the model properties or just single image, never both.
Here is my angulajs code:
angular.module('MovieController', [])
.controller('MovieCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.model = {};
$http.get('/Manage/AddMovieVM').success(function (data) {
$scope.model = data;
});
$scope.addMovie = function () {
$http.post('/Manage/Add', $scope.new.Movie).success(function (data) {
$scope.model.Movies.push(data);
$scope.showAddForm(false);
});
};
//upload files
var formData = new FormData();
$scope.LoadFileData = function (files) {
for (var file in files) {
formData.append("file", files[file]);
}
};
$scope.submit = function () {
$http.post("/Manage/Edit", formData, {
withCredentials: true,
headers: { 'Content-Type': undefined },
transformRequest: angular.identity
}).success(function (response) {
console.log('succes');
});
};
}]);
Here is my back-end code, ASP.NET MVC:
[HttpPost]
public ActionResult Add(Movie model, HttpPostedFileBase file)
{
var files = Request.Files;
var fileName = Path.GetFileName(file.FileName);
if (ModelState.IsValid)
{
using (var db = new MovieSubtitlesContext())
{
var movie = new Movie()
{
MovieTitle = model.MovieTitle,
MovieDescription = model.MovieDescription,
MovieDirector = model.MovieDirector,
MovieRating = model.MovieRating,
MovieImage = fileName
};
db.Movies.Add(movie);
db.SaveChanges();
return Json(movie, JsonRequestBehavior.AllowGet);
}
}
return View();
}
Here is my view:
<input type="text" class="form-control" placeholder="Title" ng-model="new.Movie.MovieTitle" />
<textarea rows="15" cols="50" class="form-control" ng-model="new.Movie.MovieDescription" placeholder="Description"></textarea>
//director and rating similar to first input
<input id="imgInp" type="file" aria-label="Add photos to your post" class="upload" name="file" onchange="angular.element(this).scope().LoadFileData(this.files)" multiple="" accept="image/*">
I tried a lot. For example to save all in one function like this:
$scope.addMovie = function () {
$http.post('/Manage/Edit', $scope.new.Movie, formData, {
withCredentials: true,
headers: { 'Content-Type': undefined },
transformRequest: angular.identity
}).success(function (data) {
$scope.model.Movies.push(data);
$scope.showAddForm(false);
});
};
I think it is a good idea because there are two post requests but it doesn't work anyway. To my button I tried to call two functions like this but still nothing.
<button type="button" class="btn btn-success" ng-click="addMovie(); submit()">Save</button>
I really don't know what I'm doing wrong and how I can save image with other model properties. (When I'm passing the image name in my textbox it is working fine, but that's not the point, (for example I already have in my folder "batman.jpg" then I just need to pass "batman.jpg" in my:
<input type="text" class="form-control" placeholder="Img" ng-model="new.Movie.MovieImage" required />
//Update for Nadeem
MVC Controller:
[HttpPost]
public ActionResult AddMovie(Movie model, HttpPostedFileBase file)
{
if (ModelState.IsValid)
{
if (file != null && file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/Content/ImagesC"), fileName);
file.SaveAs(path);
model.MovieImage = fileName;
}
using (var db = new MovieSubtitlesContext())
{
var movie = new Movie()
{
MovieTitle = model.MovieTitle,
MovieDescription = model.MovieDescription,
MovieDirector = model.MovieDirector,
MovieGenre = model.MovieGenre,
MovieDuration = model.MovieDuration,
MovieTrailer = model.MovieTrailer,
ImdbLink = model.ImdbLink,
MovieRating = model.MovieRating,
MovieImage = model.MovieImage,
ReleaseDate = model.ReleaseDate
};
db.Movies.Add(movie);
db.SaveChanges();
return Json(movie, JsonRequestBehavior.AllowGet);
}
}
return View();
}
Here is also my angularjs controller code for AddMovie
$scope.uploadPic = function (file) {
file.upload = Upload.upload({
url: '/Manage/AddMovie',
data: {
file: file,
MovieTitle: $scope.new.Movie.MovieTitle,
MovieDescription: $scope.new.Movie.MovieDescription,
MovieDirector: $scope.new.Movie.MovieDirector,
ReleaseDate: $scope.new.Movie.ReleaseDate,
MovieGenre: $scope.new.Movie.MovieGenre,
MovieDuration: $scope.new.Movie.MovieDuration,
MovieTrailer: $scope.new.Movie.MovieTrailer,
ImdbLink: $scope.new.Movie.ImdbLink,
MovieRating: $scope.new.Movie.MovieRating
}
});
file.upload.then(function (response) {
$timeout(function () {
file.result = response.data;
});
}, function (response) {
if (response.status > 0)
$scope.errorMsg = response.status + ': ' + response.data;
}, function (evt) {
// Math.min is to fix IE which reports 200% sometimes
file.progress = Math.min(100, parseInt(100.0 * evt.loaded / evt.total));
});
};
I am creating an email application that makes RESTful calls to Google APIs. I am using AngularJS and Java. I have had some success so far but I am unable to delete an email because I keep getting this error: TypeError: object is not a function.
My Angular knowledge is limited.
In my html I call the function deleteEmail and pass an email id.
Here is the controller:
app.controller('InboxController', function($rootScope, $scope, $cookies,
$location, InboxService) {
$rootScope.loggedIn = true;
$scope.emails = InboxService.getMessages().success(function(jsonData) {
$scope.emails = jsonData;
});
$scope.deleteEmail = function(id) {
$scope.id = {
'id' : id
};
// Parse to JSON
var responseJSON = angular.toJson($scope.id);
// Make call to InboxService
var response = InboxService().del(responseJSON).success(
function(jsonData) {
response = jsonData;
if (response == 'success') {
alert('Message deleted');
} else {
alert('Message not deleted');
}
});
}
});
The method $scope.emails works fine. It is the $scope.deleteEmail that is giving the error.
Here is the service:
app.factory('InboxService', function InboxService($http) {
var exports = {};
// Get a list of all emails
exports.getMessages = function() {
return $http.get('resources/inbox/get').error(function(data) {
console.log('There was an error!', data);
});
};
// Delete an email
exports.del = function(id) {
console.log('id ' + id);
return $http({
method : 'POST',
url : 'resources/inbox/delete',
data : id,
headers : {
'Content-Type' : 'application/json'
}
});
};
return exports;
});
I don't think I am getting as far as the service though. The problem seems to be with the controller.
Console output:
TypeError: object is not a function
at Scope.$scope.deleteEmail (http://localhost:8080/NewProject/js/controllers.js:64:18)
at Parser.functionCall (http://localhost:8080/NewProject/bower_components/angular/angular.js:10903:21)
at ngEventDirectives.(anonymous function).compile.element.on.callback (http://localhost:8080/NewProject/bower_components/angular/angular.js:19259:17)
at Scope.$get.Scope.$eval (http://localhost:8080/NewProject/bower_components/angular/angular.js:12811:28)
at Scope.$get.Scope.$apply (http://localhost:8080/NewProject/bower_components/angular/angular.js:12909:23)
at HTMLButtonElement.<anonymous> (http://localhost:8080/NewProject/bower_components/angular/angular.js:19264:23)
at http://localhost:8080/NewProject/bower_components/angular/angular.js:2853:10
Pls be sure you called deleteEmail(id) from within html with right syntax without $scope
I got it working. I changed the Controller delete method to this:
$scope.delete = function (id) {
InboxService.delete(id).success(function() {
$scope.loadInbox();
});
};
And the Service method to this:
// Delete an email
exports.delete = function(id) {
console.log('id ' + id);
return $http({
method : 'DELETE',
url : 'resources/inbox/delete',
data: id,
headers : {
'Content-Type' : 'application/json'
}
});
}
I have a model that I am using to hold my data in angular:
var FuelProcessingModel = function (carrierService) {
this.myArray = [];
};
That model has an array of MyObjects that I get from the DB:
var MyObject = function () {
//stuff
}
I update this using a REST call:
$scope.add = function () {
var myObject = new MyObject();
$scope.model.MyObjects.push(myObject);
service.add(myObject);
};
Which I use a service to hit the Server:
this.add = function (myObject) {
$http({
method: "POST",
url: "theServer",
data: myObject
});
}
The REST service just adds to the database, It doesn't return anything.
I need to reload the data from the database after the update is finished, so that my records now have all newly associated ID's and pertinent data.
I cannot just do:
window.location.reload();
The user starts by selecting a value from a drop down list to decide which list of data they start off seeing. I cannot / do not want to pass the value to it, mainly because it is in its own partial view, with its own controller, because it is used on many pages.
I tried doing:
$scope.add = function () {
//same as above
//this
service.get().then(function(result) { $scope.model.myArray = result.data; });
};
Obviously the problem here is the promise isn't complete before the DOM reloads the page. So the user saw themself add an item to the array and it vanished.
Do I want to load the page after the promise is complete? (How would I do that?)
should I return the updated data from the REST service and reset the current value? (seems like the same promise issue)
Is there a better practice that I do not know about?
UPDATE
For Bergi:
this.get = function (key) {
return $http({
method: "GET",
url: "theServer" + key
})
.success(function (data) {
return data;
});
}
I think you want to chain your two promises:
$scope.add = function () {
var myObject = new MyObject();
$scope.model.MyObjects.push(myObject);
return service.add(myObject).then(function() {
return service.get();
}).then(function(result) {
$scope.model.myArray = result.data;
});
};
and
this.add = function(myObject) {
return $http({
// ^^^^^^ return a promise here
method: "POST",
url: "theServer",
data: myObject
});
};
You can wrap your service call in a deferred promise, and on return success re-init your data from the controller..
$scope.add = function () {
var myObject = new MyObject();
$scope.model.MyObjects.push(myObject);
service.add(myObject).then(function (response) {
// here's where you'd do whatever you want to refresh your model
}),
function (err) {console.log(err);};
};
And the service:
this.add = function (myObject) {
var deferred = $q.defer();
$http({
method: "POST",
url: "theServer",
data: myObject,
success: function (response) {
deferred.resolve(err);
},
error: function (err) {
deferred.reject(err);
}
});
return deferred.promise;
}