I'm working on retrieving list of Movie Details from DB using WebAPi. I've http verbs and it does work as normal. I've a scenario where i've to get records based on categories like Title, Date, Rating
WebConfig:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional, action = "ActionName" }
Controller :
[HttpGet]
[GET("api/GetMovieByCategory/{movieData}")]
public IEnumerable<MovieData> GetMovieByCategory(MovieData movieData)
{
IEnumerable<MovieData> movieDataByCat = null;
string[] paramCast;
if(movieData.Cast.Count()!=0)
paramCast = movieData.Cast;
IEnumerable<MovieData> GetAllMovies = null;
GetAllMovies = repo.GetAll();`
if (movieData.Cast == null || movieData.Cast.Count() == 0)
{
movieDataByCat = from data in GetAllMovies
where (data.Classification == (movieData.Classification == null ? string.Empty : movieData.Classification) ||
data.Genre == (movieData.Genre == null ? string.Empty : movieData.Genre) ||
data.Rating == movieData.Rating ||
data.ReleaseDate == movieData.ReleaseDate ||
data.Title == (movieData.Title == null ? string.Empty : movieData.Title))
select data;
}
return movieDataByCat;
}
Angular Service :
//GetByCategory
this.getbyCat = function (Movie) {
return $http.get("/api/values/GetMovieByCategory/" + Movie);
};
when i try to execute, i'm getting an exception as follows,
Remote Address:[::1]:50948
Request URL:http://localhost:50948/api/values/GetMovieByCategory/[object%20Object]
Request Method:GET
Status Code:404 Not Found
I've no idea how to overcome this and get it resolved. I'm in beginner level. Please help.
Rest of all verbs (get,put,post) are working fine.
Note : I've installed NugetPackage AttributeRouting.Web.Http; for Route.
Update 1 :
Contoller.js :
$scope.srchbycat = function () {
var Movie = {
_title:"",
_genre: "",
_classification:"",
_releaseDate: "",
_rating: "",
_cast: ""
};
Movie = {
_title: $scope.txttitle,
_genre: $scope.txtGenre,
_classification: $scope.txtClassification,
_releaseDate: $scope.txtDate,
_rating: $scope.user.txtRating,
_cast: $scope.txtCast
};
var promisePost = MyService.getbyCat(Movie);
Recent Error :
Remote Address:[::1]:50948
Request URL:http://localhost:50948/api/values/GetMovieByCategory/?_genre=sdf
Request Method:GET
Status Code:400 Bad Request
In the Angular Service, instead of appending the Movie object, pass it as parameter.
eg.
//GetByCategory
this.getbyCat = function (Movie) {
return $http.get("/api/values/GetMovieByCategory/", { params: Movie});
};
This will make the HTTP get with the the properties as url parameters.
And I dont think there is a need for the {movieData} parameter in the Route defined, since WebApi will automatically Serialize the url parameters to the object MovieData
eg.
index.js
angular.module('index.services', []).
factory('indexService', function ($http) {
var api = 'api/values/GetData';
var indexAPI = {};
indexAPI.getData = function (params) {
return $http.get(api, { params: params });
}
return indexAPI;
});
angular.module('index.controllers', ['index.services']).
controller('indexController', function ($scope, indexService) {
$scope.getData = function () {
var params = {
name: 'test',
age: '10'
};
$scope.errorOccured = false;
indexService.getData(params).then(function (response) {
$scope.data = response.data;
}, function (response) {
$scope.errorOccured = true;
});
}
});
angular.module('index', ['index.controllers']);
Index.cshtml
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0-beta.1/angular.js"></script>
<script src="~/Scripts/app/index.js"></script>
<div ng-app="index" ng-controller="indexController">
<button ng-click="getData()">Get Data</button>
<div ng-if="errorOccured==true">Error Occured</div>
<div ng-repeat="item in data">
<div>{{item}}</div>
</div>
</div>
DataRequestModel.cs
public class DataRequestModel
{
public string Name { get; set; }
public string Age { get; set; }
}
ValuesController.cs
public class ValuesController : ApiController
{
[HttpGet]
public IEnumerable<string> GetData([FromUri]DataRequestModel dataRequest)
{
return new string[] { dataRequest.Name, dataRequest.Age.ToString() };
}
}
Related
I have a method that makes http get request from a url, this method gets called from multiple components, each call is making the http request, so I have stored the result in an array to return the array on the second call and not make the http request again, but it is not returning the array, its making the http request again.
Here is my code:
export class ProductsService {
public currency: string = '';
public products: Product[];
// Initialize
constructor(private http: HttpClient, private toastrService: ToastrService) {
}
// Get Products
public getProducts(): Observable<Product[]> {
return this.getAllProducts();
}
private getAllProducts(): Observable<Product[]> {
if (this.products) {
return of(this.products);
} else {
return this.getIp().pipe(
switchMap(country => {
this.currency = this.getCurrency(country);
return this.http.get('http://localhost:8080/products/getAllProducts?currency=' + this.currency).pipe(
map((res: any) => {
this.products = res;
return this.products;
})
);
})
);
}
}
private getIp() {
return this.http.get<any>(('http://ip-api.com/json/?fields=countryCode')).pipe(
map(r => r.countryCode)
);
}
private getCurrency(country: string): string {
let currency;
if (country === 'JO') {
currency = 'JOD';
} else if (country === 'AE') {
currency = 'AED';
} else if (country === 'SA') {
currency = 'SAR';
} else if (country === 'GB') {
currency = 'GBP';
} else if (country === 'DE') {
currency = 'EUR';
} else if (country === 'KW') {
currency = 'KWD';
} else if (country === 'EG') {
currency = 'EGP';
} else {
currency = 'USD';
}
return currency;
}
}
what am I doing wrong here why the method is making the http request again after the first call, shouldn't the array be filled and returned?
Please note that the components are calling the method getProducts() in the ngOnInit()
You are returning the get which is an observable. Each time these methods are called they begin a new subscription to the endpoints.
public getProducts(): Observable<Product[]> {
return this.getAllProducts();
}
private getAllProducts(): Observable<Product[]> {
if (this.products) {
return of(this.products);
} else {
return this.getIp().pipe(
switchMap(country => {
this.currency = this.getCurrency(country);
return this.http.get('http:/ <== this is an observable
You need a service to sync this stuff.
I have an example service for simple state that I used to sync URL params for many components on StackBlitz that may help you.
Using Angularjs here:
I have a form where user fills up some data and clicks save button to save data :
$scope.save = function (isValid) {
if (isValid) {
if (!$scope.checkBoxChecked) {
$scope.getExistingName($scope.uName);
}
var name = $scope.uName != '' ? $scope.uName? : 'testuser';
//Call save api
}
else {
return false;
}
};
In the save method I am checking for uname, which gets it value by calling another api as below:
$scope.getExistingName = function (uName) {
myService.getDataFromApi(uName).then(function (data) {
var existingSetName = '';
if(data.length >0)
{
$scope.uName = data[i].uName;
}
});
}
The issue is $scope.uName in my Save button is always ''. I tried to debug and found out that the result from the $scope.getExistingName method
being is promise is deffered and returned after the orignal call. Because of which my $scope.uName is empty.
What am I missing here?
--Updated---
Save method:
var name = $scope.getExistingName($scope.uName);
Updated getExistingName
$scope.getExistingName = function (uName) {
return myService.getDataFromApi(uName).then(function (data) {
var existingSetName = '';
if(data.length >0)
{
return data[i].uName;
}
});
}
--This works--
if (!$scope.checkBoxChecked) {
$scope.getExistingName($scope.uName).then(function(data)
{
var name = $scope.uName != '' ? $scope.uName? : 'testuser';
//Call save api
});
}
else
{
var name = $scope.uName != '' ? $scope.uName? : 'testuser';
//Call save api
}
I am using ASP.NET MVC 5 for the back-end and Angular + Typescript for the front-end of a web application.
I am trying to upload a file to the server, but for some reason the controller is not getting the file as parameter (the parameter in the controller is null).
I'm sharing below code.
Thanks in advance!
HTML:
<input id="filePath" name="filePath" type="file" accept="image/*" />
<a id="uploadImage" ng-click="ctrl.uploadFile()">Upload</a>
Typescript:
// controller class:
uploadFile(): void {
var filePathInput: any = $("#filePath");
if (filePathInput[0].files) {
var file: any = filePathInput[0].files[0];
var resource: any = this.service.uploadFile();
resource.save(file, (result: any) => {
if (!result || !result.success) {
alert("error");
} else {
alert("ok");
}
});
}
}
// service class:
uploadFile(): ng.resource.IResourceClass<IMyResource> {
return this.$resource("/MyController/UploadImage", null, { method: "POST" });
}
Backend Controller:
[HttpPost]
public JsonResult UploadImage([FromBody]HttpPostedFileBase file)
{
if (file == null || file.ContentLength == 0)
{
return NullParameterResponse();
}
else
{
file.SaveAs("/img/" + Path.GetFileName(file.FileName));
return SuccessResponse();
}
}
TransformRequest function: This makes your request to be sent as a FormData instead as a JSon object.
formDataObject(data: any): any {
var fd = new FormData();
angular.forEach(data, function (value, key) {
fd.append(key, value);
});
return fd;
}
In your angular resource, define the save options and pass the transformRequest function you created earlier.
uploadChequeFile(): ng.resource.IResourceClass<IChequeLoanResource> {
return this.$resource<IChequeLoanResource>("/Cheque/UploadChequeImage", null,
{
save: {
method: "POST",
transformRequest: this.formDataObject,
headers: { 'Content-Type': undefined, enctype: 'multipart/form-data' }
}
});
}
In your controller, just call your save method from the resource passing your file.
var chequeFilePathInput: any = $("#chequeFilePath");
if (chequeFilePathInput[0].files) {
var resource: ng.resource.IResourceClass<services.IChequeLoanResource> = this.uLendService.uploadChequeFile();
resource.save({ "files": chequeFilePathInput[0].files[0] }, (result: any) => {
if (!result || !result.success) {
this.errorMessage = "Error al subir la imagen al servidor. Por favor contáctanos si el error persiste.";
} else {
this.chequeLoan.cheque.filePath = result.message;
this.saveChequeLoan();
}
});
} else {
this.errorMessage = "La imagen del cheque es requerida.";
}
Finally, your controller must receive the IList parameters (with the same name defined in your angular controller)
public JsonResult UploadChequeImage(IList<IFormFile> files)
{
try
{
if (files != null && files.Count > 0)
{
return CreateResponse(true, CreateFile(files[0], #"img\cheques"));
}
I have a problem code.
like this
View
<div ng-app="MyPct4" ng-controller="ajaxCtrl">
<div>
<table>
<tr>
<td><b>pls input Color</b></td>
<td><input type="text" ng-model="InputColor" /></td>
</tr>
</table>
<input type="button" value="save" ng-click="AddUpdateColor()" />
</div>
</div>
Angularjs controller
var ptc4 = angular.module("MyPct4", []);
ptc4.controller('ajaxCtrl', function ($scope, myService) {
$scope.AddUpdateColor = function () {
var newColor = { Color: $scope.InputColor };
var getData = myService.AddColor(newColor);
getData.then(function (msg) {
alert(msg.data);
}, function () {
alert("error")
});
}
}
Angularjs service
ptc4.service("myService", function ($http) {
this.AddColor = function (newColor) {
var response = $http({
method: "post",
url: "/Practice/AddColor",
data: JSON.stringify(newColor),
dataType: "json"
});
return response;
}
}
MVC controller
private TestDBEntities2 db = new TestDBEntities2();
public string AddColor(ColorDB color)
{
if (color != null)
{
db.ColorDB.Add(color);
db.SaveChanges();
return "add success";
}
else
{
return "add fail";
}
}
The result is always show alert add fail.
Seems to be json can't post to MVC controller.
Please help thank you so much.
ColorDB
public partial class ColorDB
{
public int Id { get; set; }
public string Color { get; set; }
}
update:
I changed AddColor controller code.I also tyr to add ColorDB color = new ColorDB();
and color.Color = "testColor";The value can insert to db but ColorDB colalso null.The problem seems to Mvc Controller can't Receive ajax data.
public string AddColor(ColorDB col)
{
ColorDB color = new ColorDB();
color.Color = "testColor";
if (color != null)
{
db.ColorDB.Add(color);
db.SaveChanges();
return "add success";
}
else
{
return "add fail";
}
}
public string AddColor(ColorDB color) you are expecting ColorDB object. If it represents your DB then its wrong. It could not bind. Check the parametres type .
UPDATE: I think the problem is binding.The controller can't bind your json to ColourDB object.
You can try:
Add this your ajax options contentType: "application/json; charset=utf-8". Maybe dataType: "json" is not enough. And if it wont work try to use angular.TOJSON(newColor) instead of using JSON.stringify(newColor). Or combine this two.
I'm trying to post bookData to my WebAPI2 service by using the "$resource" in AngularJS. This works fine when it gets a book from the BookService first, modify the book and post it to the BookService.
I'm looking for a way posting a book without getting a book from the BookService first.
First, i have created an REST-service in WebAPI2:
public IHttpActionResult Get([FromUri] string id)
public IHttpActionResult Post([FromBody] BookData bookData)
Second, in the controller i'm trying to get en post some bookdata. The BookService is injected in the Controller
var bookData;
var book = BookService.get({ id: 1 }, function()
{
bookData = book;
});
$scope.sendBook = function () {
bookData.Title = 'Test REST';
var book = new BookService(bookData);
book.$save();
}
I've tried the following, but it doesn't work
var bookData = {Title: 'Test REST'};
$scope.sendBook = function () {
var book = new BookService(bookData);
book.$save();
}
There are only some static data in it.
public class BookController : ApiController
{
[HttpGet]
public IHttpActionResult Get([FromUri] string id)
{
BookViewModel vm = new BookViewModel
{
Title = "TEST REST"
};
return Ok(vm);
}
[HttpPost]
public IHttpActionResult Post([FromBody] BookData bookData)
{
BookViewModel vm = new BookViewModel
{
Title = "TEST REST"
};
return Created(new Url(Request.RequestUri.ToString()), vm);
}
}
I've find a solution. Assign the bookData to $scope
Something like:
$scope.bookData = { Title: 'Some title' };