Using http.get with a parameter - angularjs

I have a ui-grid with some rows.
I added a column with a link to access the details of the row and show it in a new (angularjs) view.
The new view gets its data from a http.get command.
Is there any way to transfer the "selected row" parameter to the new view so the http.get gets the right details?
At the moment I use MVC routing, so there is a Controller in between the two angular parts.
Ui-Grid:
$scope.gridOptions2 = {
enableFiltering: true,
treeRowHeaderAlwaysVisible: false,
rowHeight: 100,
columnDefs: [
{ name: 'Trigraph', field: 'ZeigeTrigraphen', width: '10%' },
{ name: 'Titel', field: 'Titel', cellTemplate: '<td style="word-wrap:break-word;padding:5px;">{{ COL_FIELD }}</td>' },
{name: 'Aktionen',field:'AlarmkalenderId',cellTemplate:'<i class="glyphicon glyphicon-edit"'}
],
onRegisterApi: function (gridApi2) {
$scope.gridApi2 = gridApi2;
}
};
MVC controller:
public ActionResult Details(int id)
{Viewmodel = ViewModelService.getViewmodel(id);
return View(Viewmodel)
}
http.get in the new view (the returned one above):
$http.get('/api/Alarmkalender/HoleAlarmmassnahme').then(function (resp) {
$scope.gridOptionsEinzelmassnahmen.data = resp.data.IndexEinzelmassnahmen;
$scope.data=resp.data;
$log.info(resp);
});
WebApiController Method:
public async Task<IHttpActionResult> HoleAlarmmassnahme(int alarmmassnahmeId=1)
{
detailsAlarmmassnahmeViewModel = //getting Viewmodel from a Controller/Service
return Ok(detailsAlarmmassnahmeViewModel);
}
Routes:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "404-PageNotFound",
// This will handle any non-existing urls
url: "{*url}",
// "Shared" is the name of your error controller, and "Error" is the action/page
// that handles all your custom errors
defaults: new { controller = "Shared", action = "Error" }
);
}

You can't pass data in a GET request, however you can add a query string to your request:
$http({
url: "/api/Alarmkalender/HoleAlarmmassnahme",
method: "GET",
params: {gridRow: YOUR_GRID_ROW_HERE}
});
or by adding directly your query in the url string.
$http.get("/api/Alarmkalender/HoleAlarmmassnahme?gridrow=YOUR_GRID_ROW_HERE")

Related

UI Router, Passing Data From Parent Controller

I'm attempting to refactor a website into Angular through UI-Router. On the parent component I have defined some data on the controller. How do I pass this data to the child nested routed component through UI-Router? UI-Router's resolve only works when you have a binding on data, but I don't know if it's possible to bind the parent controller data to the parent component.
const main = angular.module('main', ['ui.router']);
main.config(function($stateProvider) {
const states = [
{ name: 'parent', url: '/parent', component: 'parent' },
{ name: 'parent.child', url: '/{childUrl}', component: 'child',
resolve: {
data: function($transition$) {
// I want to pass in { name: 'Name1', content: 'Page-Long Content1' }, { name: 'Name2', content: Page-Long Content2' }
// How do I do this?
}
}
}
];
states.forEach(function(state) {
$stateProvider.state(state);
});
});
angular.module('main')
.component('parent', {
template:
'<div ng-repeat="data in $ctrl.data">' +
'<p>{{data.name}}</p>' +
'<a ui-sref="parent.child({ childUrl: data.name })" ui-sref-active="active">Child link</a>' +
'</div>' +
'<ui-view></ui-view>',
controller: function() {
this.data = [
{name: 'Name1', content: 'Page-Long Content1'},
{name: 'Name2', content: 'Page-Long Content2'}
]
}
});
angular.module('main')
.component('child', {
bindings: { data: '<' },
templateUrl: 'link.html',
});
Basically you have an unique identifier of your record in the URL. So by that you can retrieve your data once again from the dataset. For achieving the same, I'd suggest you to put your data in service and then fetch the same data in resolve of your state. Afterward apply an filter over the data and get desired record from it based on childUrl parameter of state.
angular.module('main')
.service('dataService', function(){
var dataService = this;
dataService.getData = getData;
var data = [
{name: 'Name1', content: 'Page-Long Content1'},
{name: 'Name2', content: 'Page-Long Content2'}
];
function getData(){
return data;
}
});
state
const states = [
{ name: 'parent', url: '/parent', component: 'parent' },
{ name: 'parent.child', url: '/{childUrl}', component: 'child',
resolve: {
data: function($transition$, dataService) {
let childUrl = $transition$.params('childUrl');
//in case of API call below will be changed to promise driven code.
return dataService.getData().filter((item) => item.name === childUrl)[0];
}
}
}
];
And inside a parent controller you can fetch data from service directly.
controller: function(dataService) {
this.data = dataService.getData();
}

Angular Kendo Grid Filters and Sort information Missing when hitting MVC Controller

I'm having a problem getting the filters and sort information from Kendo Grid to my MVC controller. I am using a service to pass form data and DataSource data to the MVC Controller.
Here is my Kendo Grid DataSource:
dataSource: new kendo.data.DataSource({
transport: {
read: function (e) {
generalsearchService.submitSearch(e.data, form)
.then(function success(response) {
e.success(response.data);
});
}
},
schema: {
data: "Data",
total: "Total"
},
pageSize: 25,
serverPaging: true,
serverFiltering: true,
serverSorting: true
}),
Here is the code in my service:
this.submitSearch = function (command, form) {
return $http.post('/SSQV4/SSQV5/Search/SubmitCriteria', {'command': command, 'form': form});
};
Here is my MVC Controller Method definition:
public async Task<ActionResult> SubmitCriteria(DataSourceRequest command, ContractorSearchViewModel form)
When it hits the dataSource the filter info is there:
When it hits the Service, the filter info is there:
When it hits the MVC Controller it is gone:
I tried including 'type: "aspnetmvc-ajax"', but it throws this error:
Any assistance is greatly appreciated!
Had to manually "inject" the aspnetmvc-server into the transport in order to get this to work. Here was the fix:
In the Angularjs Controller:
var form = $scope.form;
dataSource: new kendo.data.DataSource({
transport: {
read: function (e) {
var grid = $scope.SearchGrid;
var requestObject = (new kendo.data.transports["aspnetmvc-server"]({ prefix: "" }))
.options.parameterMap({
page: grid.dataSource.page(),
sort: grid.dataSource.sort(),
filter: grid.dataSource.filter(),
pagesize: grid.dataSource.pageSize()
});
generalsearchService.submitSearch({ page: requestObject.page, sort: requestObject.sort, filter: requestObject.filter, pagesize: requestObject.pagesize, form: form })
.then(function success(response) {
e.success(response.data);
});
}
},
schema: {
data: "Data",
total: "Total"
},
pageSize: 25,
serverPaging: true,
serverFiltering: true,
serverSorting: true
In the Angularjs Service:
this.submitSearch = function (form) {
return $http.post('/SSQV4/SSQV5/Search/SubmitCriteria', form );
};
In the MVC Controller:
public async Task<ActionResult> SubmitCriteria([DataSourceRequest] DataSourceRequest request, ContractorSearchViewModel form)
Everything working as it should. Hope this helps someone else. Happy coding!

Kendo-ui angular directive on editor

I'm trying to attach an angular directive to `
{
field:"stateID",
hidden: true,
title: "State",
editor: function (container, options) {
var _statesDirective = $('<div><my-states></my-states></div>');
_statesDirective.appendTo(container);
}`
My diretive looks like this:
appRoot.directive('myStates', function () {
return {
restrict: 'EA',
templateUrl: 'directivesHTML/ddStates.html',
scope:false,
controller: function ($scope)
{
var dsStates = new kendo.data.DataSource({
autoBind: false,
page: 1,
transport: {
read: {
url: "api/util/getStates",
dataType: "json"
}
},
schema: {
model: {
id: "stateID",
fields: {
stateID: { type: 'string' },
name: { type: "string" }
}
}
}
});
dsStates.read().then(function () {
$('#ddStates')
.kendoDropDownList({
dataTextField: "name",
dataValueField: "stateID",
dataSource: dsStates,
optionLabel: '--',
change: function (e) {
}
});
});
}
};
});
For some weird reason, it wont work, if I put the directive someplace else, any outside html page, it works just fine, but not from here. I thought it could be the version, upgraded it to the latest one for this month to no avail.
Any clues ?
-thanks,
You need to compile your html before appending it (using $compile service).
So in your editor: function,
// Specify what it is we'll be compiling.
var to_compile = '<div><my-states></my-states></div>';
// Compile the tag, retrieving the compiled output.
var _statesDirective = $compile(to_compile)($scope);
// Ensure the scope and been signalled to digest our data.
$scope.$digest();
// Append the compiled output to the page.
$compiled.appendTo(_statesDirective);
For more reference, Angular Docs for $compile
Also, how can we use $compile outside a directive in Angularjs

asp.net web api call custom method using angularJS

i have a angularJS controller where i put a kendo cascade dropdownlist.For dropdown list value ,on kendo dataSource read i am calling the web api service.
For the first field the api GetDivisions() has been called and it response also but for the 2nd value the GetCascadeDistrict() method not called the GetDivisions() method called again. How can i solve this.Need Help
here's the angular Controller with kendo cascade dropdownlist.
app.controller("filterCtrl", function($scope, $sce,$http) {
var i;
$scope.dashImgSrc = $sce.trustAsResourceUrl('Content/Images/Bangladesh_Govt.gif');
$(document).ready(function () {
var divisions = $("#divisions").kendoComboBox({
filter: "contains",
placeholder: "select a divisions...",
dataTextField: "Name",
dataValueField: "Id",
animation: {
close: {
effects: "zoom:out",
durations:250
}
},
dataSource: {
type: "json",
serverFiltering: true,
transport: {
read: "api/AreaService/GetDivisions()"
}
},
change: function () {
i = divisions.value();
alert("1st hit"+i);
}
}).data("kendoComboBox");
var districts = $("#districts").kendoComboBox({
autoBind: false,
cascadeFrom: "divisions",
filter: "contains",
placeholder: "select a district",
dataTextField: "Name",
dataValueField: "Id",
dataSource: {
type: "json",
serverFiltering: true,
transport: {
read: function () {
alert("2nd hit");
//$http.get("/api/AreaService/GetCascadeDistrict(i)").success(function() {
// alert("Hit the district api");
//}).error(function() {
// alert("Error");
//});
$http({ method: "GET", url: 'api/AreaService/GetCascadeDistrict(i)' }).
success(function() {
alert("Actually it hit the custome get method");
}).
error(function() {
alert("Not hit or other problem");
});
}
}
}
}).data("kendoComboBox");
var upazila = $("#upazila").kendoComboBox({
autoBind: false,
cascadeFrom: "districts",
filter: "contains",
placeholder: "select a upazila...",
dataTextField: "Name",
dataValueField: "Id",
dataSource: {
type: "json",
serverFiltering: true,
transport: {
read: function() {
$http.get("/api/AreaService/GetCascadeDistrict(i)").success(function() {
}).error(function() {
});
}
}
}
}).data("kendoComboBox");
$("#get").click(function () {
var divisionInfo = "\Division: { id: " + divisions.value() + ", name: " + divisions.text() + " }",
districtInfo = "\nDistrict: { id: " + districts.value() + ", name: " + districts.text() + " }",
upazilaInfo = "\nUpazila: { id: " + upazila.value() + ", name: " + upazila.text() + " }";
alert("Road details:\n" + divisionInfo + districtInfo + upazilaInfo);
});
});
});
And the Web api is here
public class AreaServiceController : ApiController
{
private readonly AreaFilterManager _db = new AreaFilterManager();
[System.Web.Http.HttpGet]
public IEnumerable<Division> GetDivisions()
{
return _db.GetDivisions();
}
[System.Web.Http.HttpGet]
public IEnumerable<District> GetCascadeDistrict(int? division)
{
return _db.GetCascadeDistrict(division);
}
[System.Web.Http.HttpGet]
public IEnumerable<Thana> GetCascadeUpzilla(int? district)
{
return _db.GetCascadeThana(district);
}
}
You'll need to separate/distinguish your calls by CRUD operations or by Attribute Routing depends your WebApi version your using in your project.
You cannot use the same CRUD HttpGet twice in the same Class/Controller without putting a different routing attribute.
You need to remember, in WebApi the methods are not being called by their names like in regular programming, therefore the WebApi Class/Controller doesn't know which method you meant to call from your Client (in your case).
That's why you'll need to:
WebApi Ver 1 : separate/distinguish your calls by CRUD operations.
WebApi Ver 2 : separate/distinguish your calls by Attribute Routing.

Kendo UI Angular JS and AutoComplete with a service

I'm making an Angular App and I'm starting to use some of the Kendo UI controls. I'm having some issues wiring up the AutoComplete control. I would like to use a factory that will return the list of "auto complete" values from my database.
I have iincluded the auto complete control and I'm trying to use the k-options attribute:
<input kendo-auto-complete ng-model="myFruit" k-options="FruitAutoComplete" />
In my controller the following hard coded list of fruits work:
$scope.FruitAutoComplete = {
dataTextField: 'Name',
dataSource:[
{ id: 1, Name: "Apples" },
{ id: 2, Name: "Oranges" }
]
}
When I move this over to use my factory I see it calling and returning the data from the factory but it never get bound to the screen.
$scope.FruitAutoComplete = {
dataTextField: 'Name',
dataSource: new kendo.data.DataSource({
transport: {
read: function () {
return FruitFactory.getYummyFruit($scope.myFruit);
}
}
})
}
I end up with the request never being fulfilled to the auto complete.
My factory is just returning an array of fruit [
my Fruit Factory Code:
getYummyFruit: function (val) {
return $http.get('api/getFruitList/' + val)
.then(function (res) {
var fruits= [];
angular.forEach(res.data, function (item) {
fruits.push(item);
});
return fruits;
});
}
Here is your solution
http://plnkr.co/edit/iOq2ikabdSgiTM3sqLxu?p=preview
For the sake of plnker I did not add $http (UPDATE - here is http://plnkr.co/edit/unfgG5?p=preview with $http)
UPDATE 2 - http://plnkr.co/edit/01Udw0sEWADY5Qz3BnPp?p=preview fixed problem as per #SpencerReport
The controller
$scope.FruitAutoCompleteFromFactory = {
dataTextField: 'Name',
dataSource: new kendo.data.DataSource({
transport: {
read: function (options) {
return FruitFactory.getYummyFruit(options)
}
}
})
}
The factory -
factory('FruitFactory', ['$http',
function($http) {
return {
getYummyFruit: function(options) {
return $http.get('myFruits.json').success(
function(results) {
options.success(results);
});
}
}
}

Resources