asp.net web api call custom method using angularJS - 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.

Related

Generate a Ajax Radio List

I need to create a list of clickable radio buttons that gets generated through an ajax request. They will look like this:
10/15/2018
10/14/2018
10/13/2018
....
So I am doing the Ajax call below and getting the result:
onTabChange: function (tabPanel, tab) {
if (tab.getTitle() == 'Reconciliation') {
Ext.Ajax.request({
url: '***',
reader: {
type: 'json',
rootProperty: 'data'
},
useDefaultXhrHeader: false,
withCredentials: true,
scope: this,
success: function (response) {
var selectReconciliation = this.lookupReference('lisatradereconciliation');
// Get the data from Ajax Request and shape it
var data = Ext.JSON.decode(response.responseText).data;
var reconciliationItems = [];
// Put the data into a shape that it will need to look like on the page
for (var i in data) {
reconciliationItems.push("boxLabel: '" + data[i].substr(5, 2) + "/" + data[i].substr(8, 2) + "/" + data[i].substr(0, 4) +"', name: 'rI', inputValue: 'data[i]'");
}
},
failure: function (response) {
'***'
}
});
}
},
Which then I am sending it to the view radiogroup item as follows:
items: [{
xtype: 'radiogroup',
fieldLabel: 'day',
items: reconciliationItems
}]
But this doesn't work.
The reconciliationItems array should be defined as a global variable, or outside of your ajax success handler, to achieve what you want:
Define the array outside of success:
window.reconciliationItems = [];
And then access it in the success handler like so:
success: function (response) {
var selectReconciliation = this.lookupReference('lisatradereconciliation');
// Get the data from Ajax Request and shape it
var data = Ext.JSON.decode(response.responseText).data;
// var reconciliationItems = []; <-- Dont define here
// Put the data into a shape that it will need to look like on the page
for (var i in data) {
reconciliationItems.push("boxLabel: '" + data[i].substr(5, 2) + "/" + data[i].substr(8, 2) + "/" + data[i].substr(0, 4) +"', name: 'rI', inputValue: 'data[i]'");
}
},

Using http.get with a parameter

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")

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);
});
}
}
}

Issue with my custom select2 directive for angularjs

I have created custom select2 directive for angular it works perfect for my usecase and works like charm when i use template and it sets and get the values from input/ngModel
but when i use it on view page it do not resolve ngModel via scope.$eval
this is something scope issue please help me on this
please find directive mentioned below:
(function () {
'use strict';
var directiveId = 'snSelect2';
angular.module('app').directive(directiveId, ['datacontext', snSelect2]);
function snSelect2(datacontext) {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, controller) {
var urlPrefix =datacontext.urlPrefix;
$(function () {
element.select2({
placeholder: element.attr('placeholder'),
multiple: angular.isDefined(attrs.multiple),
minimumInputLength: 3,
blurOnChange: true,
ajax: { // instead of writing the function to execute the request we use Select2's convenient helper
url: urlPrefix + "/Employees",
dataType: 'json',
data: function (term) {
return {
term: term
};
},
results: function (data) { // parse the results into the format expected by Select2.
// since we are using custom formatting functions we do not need to alter remote JSON data
return { results: data };
}
},
initSelection: function (element, callback) {
var id = scope.$eval(attrs.ngModel);//$(element).val();
if (id != "") {
$.ajax(urlPrefix + "/EmployeeById",
{
data: {
id: id,
format: 'json'
},
datatype: 'json'
}).done(function (data) {
if (angular.isDefined(attrs.multiple)) {
callback(data);
}
else {
callback(data[0]);
}
});
}
//var data = {id: element.val(), text: element.val()};
//callback(data);
},
dropdownCssClass: "bigdrop", // apply css that makes the dropdown taller
escapeMarkup: function (m) { return m; } // we do not want to escape markup since we are displaying html in results
}).select2('val', scope.$eval(attrs.ngModel))
.on("change", function (e) {
scope.$apply(function () {
controller.$setViewValue(attrs.ngModel);
});
});
element.bind("change", function (e) {
scope.$apply(function () {
scope[attrs.ngModel] = e.val;
});
});
});
}
}
}})();
http://snag.gy/lcizI.jpg
<!-- html element -->
<input type="hidden" class="form-control" data-ng-model="show" ui-select2="getShow">
$scope.getShow = {
placeholder: "Enter Show Code",
minimumInputLength: 3,
escapeMarkup: function (m) { return m; },
formatSelection: function(obj, container) {
return "ID: " + obj.showid + " - " + obj.name;
},
formatResult: function(obj, container, query) {
var start = obj.startdate ? moment(obj.startdate).format("DD/MM/YYYY") : "Unknown";
var end = obj.enddate ? moment(obj.enddate).format("DD/MM/YYYY") : "Unknown";
return '<div class="list-group-item small">' +
'<i><span class="label label-default pull-right">ID: ' + obj.showid + '</span></i>' +
'<i><span class="label label-info">(' + obj.code + ')</span></i>' +
'<div style="padding-top: 4px"><strong>' + obj.name + '</strong></div>' +
'<i>' + start + " - " + end + '</i>' +
'</div>';
},
query: function(options) {
if (!options.context)
options.context = {};
// status == processing means http request is in process, so don't do it again
if (options.context.status === "processing")
return;
options.context.status = "processing";
// this is just like ajax $http.get("/search").
model.show.search("search", {code: options.term, limit: 10, sort: 'ts desc'} )
.then(function(result) {
// set status = completed to indicate http request finished.
options.context.status = "completed";
// when you get the result from ajax, callback require you to call with
// an object { results: your result } as result
$scope.list.datalist.show = result;
options.callback({
results: result
});
});
}
}
Data from server looks like
[{
code: "MELCCS"
enddate: "2014-03-10T14:00:00.000Z"
id: "5329c28087b375a4d8a2af43"
name: "Melbourne Caravan and Camping Show"
openinghour: ""
showid: 1810
startdate: "2014-03-05T14:00:00.000Z"
state: "VIC"
status: "Research"
ts: 1395245779280
updatedAt: "2014-03-21T09:16:56.859Z"
warehouse: "52ecd53b673a5fba428e21a7"
}]

create/update user story using rally app sdk

Until now, I have been querying the data stores using Rally App SDK, however, this time I have to update a story using the js sdk. I tried looking up for examples for some sample code that demonstrates how the App SDK can be used to update/add values in Rally. I have been doing CRUD operations using Ruby Rally API but never really did it with the app sdk.
Can anyone provide some sample code or any link to where I could check it out?
Thanks
See this help document on updating and creating reocrds. Below are examples - one updates a story, the other creates a story. There is not much going on in terms of UI: please enable DevTools console to see console.log output.
Here is an example of updating a Defect Collection on a User Story:
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
console.log("launch");
Rally.data.ModelFactory.getModel({
type: 'User Story',
success: this._onModelRetrieved,
scope: this
});
},
_onModelRetrieved: function(model) {
console.log("_onModelRetrieved");
this.model = model;
this._readRecord(model);
},
_readRecord: function(model) {
var id = 13888228557;
console.log("_readRecord");
this.model.load(id, {
fetch: ['Name', 'Defects'],
callback: this._onRecordRead,
scope: this
});
},
_onRecordRead: function(record, operation) {
console.log('name...', record.get('Name'));
console.log('defects...', record.get('Defects'));
if(operation.wasSuccessful()) {
//load store first by passing additional config to getCollection method
var defectStore = record.getCollection('Defects', {
autoLoad: true,
listeners: { load: function() {
//once loaded now do the add and sync
defectStore.add({'_ref':'/defect/13303315495'});
defectStore.sync({
callback: function() {
console.log('success');
}
});
}}
});
}
},
});
Here is an example of creating a user story, setting a project and scheduling for an iteration:
Ext.define('CustomApp', {
extend: 'Rally.app.TimeboxScopedApp',
componentCls: 'app',
scopeType: 'iteration',
comboboxConfig: {
fieldLabel: 'Select an Iteration:',
labelWidth: 100,
width: 300
},
addContent: function() {
this._getIteration();
},
onScopeChange: function() {
this._getIteration();
},
_getIteration: function() {
var iteration = this.getContext().getTimeboxScope().record.get('_ref');
console.log('iteration',iteration);
if (!this.down('#b2')) {
var that = this;
var cb = Ext.create('Ext.Container', {
items: [
{
xtype : 'rallybutton',
text : 'create',
id: 'b2',
handler: function() {
that._getModel(iteration);
}
}
]
});
this.add(cb);
}
},
_getModel: function(iteration){
var that = this;
Rally.data.ModelFactory.getModel({
type: 'UserStory',
context: {
workspace: '/workspace/12352608129'
},
success: function(model) { //success on model retrieved
that._model = model;
var story = Ext.create(model, {
Name: 'story 777',
Description: 'created via appsdk2'
});
story.save({
callback: function(result, operation) {
if(operation.wasSuccessful()) {
console.log("_ref",result.get('_ref'), ' ', result.get('Name'));
that._record = result;
that._readAndUpdate(iteration);
}
else{
console.log("?");
}
}
});
}
});
},
_readAndUpdate:function(iteration){
var id = this._record.get('ObjectID');
console.log('OID', id);
this._model.load(id,{
fetch: ['Name', 'FormattedID', 'ScheduleState', 'Iteration'],
callback: function(record, operation){
console.log('ScheduleState prior to update:', record.get('ScheduleState'));
console.log('Iteration prior to update:', record.get('Iteration'));
record.set('ScheduleState','In-Progress');
record.set('Iteration', iteration);
record.set('Project', '/project/12352608219')
record.save({
callback: function(record, operation) {
if(operation.wasSuccessful()) {
console.log('ScheduleState after update..', record.get('ScheduleState'));
console.log('Iteration after update..', record.get('Iteration'));
}
else{
console.log("?");
}
}
});
}
})
}
});

Resources