How to pass json object as GET using $resource in angular? - asp.net

How to pass json object to WebApi as GET using $resource in angular?
My service:
pmsService.factory('Widgets', ['$resource', function ($resource) {
var data = $resource('/api/:path/:id', {
path: '#path'
}, {
getWidgets: {
params: { path: 'widgets' },
method: "GET",
isArray: true
},
getWidget: {
params: { path: 'widgets' },
method: "GET",
isArray: false
},
getWidgetData: {
params: { path: 'widgets' },
method: "POST"
},
});
return data;
In angular controller:
Widgets.getWidgetData({ id: $scope.widget.id}, $scope.paramValues ).$promise.then(function (data) {
$scope.widget.Data = data;
$log.debug($scope.widget.Data);
});
In Controller:
[Route("api/widgets/{id}")]
[HttpPost]
public Object Get(int id, dynamic prms)
{
....
}
This should sends 2 parameters to WebApi Controller, id and list of parameters for the Widget. Fiddler shows:
/api/widgets/31/%5Bobject%20Object%5D
So routing works correctly, but the object prms I received is empty.

I don't really understand what you're trying to do there but
if you're trying to achieve a url parameter as in /api/widgets/31?foo=bar, then this is how I would do it.
angular
.module('myMod', ['$resource'])
.factory('Widgets',
['$resource', function ($resource) {
return $resource(
'/api/:path/:id/',
{'path': '#path'},
{
getWidgets: {
params: {path: 'widgets'},
method: "GET",
isArray: true
},
getWidget: {
params: {path: 'widgets'},
method: "GET",
isArray: false
},
getWidgetData: {
params: {path: 'widgets'},
method: "GET",
isArray: false
}
})
}])
.controller('WidgetsController',
['$scope', 'Widgets', function ($scope, Widgets) {
$scope.widget = Widgets.getWidget({
id: 1,
foo: 'bar'
});
}]);
That would a make GET request to /api/widgets/1?foo=bar. You can include a nested object or an array like this and it will be serialised and appended to the url
// In controller
.controller('WidgetsController',
['$scope', 'Widgets', function ($scope, Widgets) {
$scope.widget = Widgets.getWidget({
id: 1,
fields: ['name', 'price']
});
}]);
This would make a GET request to /api/widgets/1?fields=name&fields=price.
I usually prefer to use the $httpParamSerializerJQLike serializer to serialize the parameters in this form /api/widgets/1?fields[]=name&fields[]=price which in my experience is less problematic. To use this serializer, you need to configure $http like so
angular
.module('myMod')
.config(['$httpProvider', function ($httpProvider) {
$httpProvider.defaults.paramSerializer = '$httpParamSerializerJQLike';
}])
Hope that helps

Related

Meteor: Pulling variable from iron router to a template

I am trying to get two variable from the iron router so that I can essentially call them in my temlate such as {{user.telephone}} and {{pic.profilepic}}.
My code in the router is as follows. (Does Not Work!)
Router.route('/profile/:_id', {
name: 'profile',
template: 'profile',
data:function(){
return {
user:Info.findOne({_id:this.params._id}),
pic: Profilepics.findOne({_id:this.params._id})
};
},
subscriptions: function(){
return {
Meteor.subscribe("userInfo"),
Meteor.subscribe( "profilepic");
},
action:function (){
if (this.ready()){
this.render();
}else {
this.render('loading');
}
}
});
I able to do just one variable with the following code. i.e get {{user.telephone}}. Any chance anyone can help me get both variable instead of just one?
enterRouter.route('/profile/:_id', {
name: 'profile',
template: 'profile',
data:function(){
return {
user:Info.findOne({_id:this.params._id})
};
},
subscriptions: function(){
return Meteor.subscribe("userInfo")
},
action:function (){
if (this.ready()){
this.render();
}else {
this.render('loading');
}
}
});
If you are using the latest version of iron router, i suggest you update the code to something a bit more modern.
First you create a general app controller:
ApplicationController = RouteController.extend({
layoutTemplate: 'DefaultLayout',
loadingTemplate: 'loading_template',
notFoundTemplate: '404_template',
});
Then you start to extend it for different purposes:
ProfileController = ApplicationController.extend({
show_single: function() {
this.render('profile');
}
});
After this you can create your routes for the profile part
Router.route('/profile/:_id', {
controller: 'ProfileController',
action: 'show_single',
waitOn: function() {
return [
Meteor.subscribe("userInfo"),
Meteor.subscribe("profilepic")
];
},
subscriptions: function() {
this.subscribe("somethingyoudontneedtowaitfor", this.params._id);
},
data: function() {
if (this.ready()) {
return {
user: Info.findOne({
_id: this.params._id
}),
pic: Profilepics.findOne({
_id: this.params._id
})
};
}
}
});
It might be a bit more code, but it gives you complete control over what it does. Also, using this, while the router is waiting for the subscriptions to be ready, it displays the loading template defined above. If you don't want to display the loading, you move the subscriptions out of waiton.
Return multiple subscriptions as an array from subscriptions function,
Use return [
Meteor.subscribe("userInfo"),
Meteor.subscribe( "profilepic")
];
instead of
return { Meteor.subscribe("userInfo"), Meteor.subscribe( "profilepic"); which has {} mismatch.
In a similar situation I have
data: function() {
var gridId = this.params._gridId;
return (People.find({gridId: gridId})
&& GridLog.find({gridId: gridId}));
},
with the subscribe calls in the waitOn() handler as part of the Boolean status
waitOn: function() {
return (Meteor.subscribe('people', this.params._gridId)
&& Meteor.subscribe('gridlog', this.params._gridId) );
},
You may have more success just &&ing them together in waitOn() (as strange as that seems).

Kendo AutoComplete Empty Filter in Querystring - serverfiltering

I'm trying to use serverfiltering for autocomplete in Kendo UI (ASP.NET 5, MVC6)
Due to fact that Autocomplete isn't available in MVC Wrapper, i had to use the code below:
<script>
var dataSource = new kendo.data.DataSource({
serverFiltering: true,
serverOperation: true,
type: "aspnetmvc-ajax",
transport: {
read: {
url: "#Url.Content("~/api/Get")",
type: "GET"
}
},
schema: {
data: "Data",
total: "Total"
}
})
$("##Model.Name").kendoAutoComplete({
placeholder: "#Model.Watermark",
minLength: 3,
filter: "contains",
dataSource: dataSource
});
</script>
The problem is that querystring send to controller looks like this :
?sort=&group=&filter=
So it doesn't include any filter information
On serverside im trying to map it to DataSourceRequest
Right now im using following workaround to pass additional parameter to do serversidefiltering but still i'd like to use kendo native filtering for this:
<script>
var dataSource = new kendo.data.DataSource({
serverFiltering: true,
serverOperation: true,
type: "aspnetmvc-ajax",
transport: {
read: {
url: "#Url.Content("~/api/Get")",
type: "GET",
data: onAdditionalData
}
},
schema: {
data: "Data",
total: "Total"
}
})
$("##Model.Name").kendoAutoComplete({
placeholder: "#Model.Watermark",
minLength: 3,
filter: "contains",
dataSource: dataSource
});
function onAdditionalData() {
return {
text: $("##Model.Name").val()
};
}
</script>
Controller code:
[Route("api/Get")]
[HttpGet]
public JsonResult Get([DataSourceRequest] DataSourceRequest request, string text = "")
{
var list = (new List<string>() { "value1", "value2", "value3", "test" } ).AsQueryable();
return Json(list.Where(x => x.Contains(text)).ToDataSourceResult(request));
}

Change components with ajax. (Ractivejs)

views.list = Ractive.extend({/*...*/});
var Content = Ractive.extend({
template: '#template-content',
components: {
//view: views['list']
},
onrender: function() {
/* call this.request */
},
request: function(route) {
var self = this;
$.ajax({
url: route,
type: 'GET',
data: {},
dataType: 'json',
success: function(data){
self.components.view = views[data.view];
}
});
}
});
Ajax request returns {view:'list'}. I write in the console: "Content.components.view" and see:
function ( options ) {
initialise( this, options );
}
But "Content.findComponent('view')" returns "null".
It will work if I uncomment the line "//view: views['list']" in the components. How to dynamically change the component?
Update 1:
I thought I can do this:
var Content = Ractive.extend({
components: {
// Aaaand add listener for data.view?
view: function(data) {
return views[data.view];
// But no, it is not updated when changes data.view ...
}
},
data: {},
oninit: function() {
var self = this;
self.set('view', 'list');
},
});
Not work.. Why then need "data" argument?
I won :)
// Create component globally
Ractive.components.ListView = Ractive.extend({});
// Create ractive instance
var Content = Ractive.extend({
template: '#template-content',
partials: {
view: 'Loading...' // So... default
},
oninit: function() {
var self = this;
$.ajax({
...
success: function(data){
// Hardcore inject component
self.partials.view = '<'+data.view+'/>';
// Little hack for update partial in template
self.set('toggle', true);
self.set('toggle', false);
}
});
},
});
In Content template:
{{^toggle}}{{>view}}{{/}}
It's works-fireworks!

Overwriting RouteController settings

I have a route controller like so:
StudentPageFeeds = RouteController.extend({
waitOn: function() {
Meteor.subscribe('headers', this.route.name)
},
data: function() {
return Headers.findOne({});
}
});
And I have a route:
this.route('teacher', {
path: 'teacher/:_id',
data: function() {
return Meteor.users.findOne({_id: this.params._id});
},
controller: StudentPageFeeds
});
When I do this, the route data is not returned. Removing the route controller fixes the issue however. How can I get the data from the route, if I need to keep the route controller?

How to Specify Full Url of WCF Service in Angularjs $resource

I have wcf service with method GetLayoutData. Following code i have written for this:
var app = angular.module('bundleModuleApp', ['ngResource', 'mydirectives']);
app.factory('masterResource', function ($resource)
{
var src = $resource("../BundleService/BundleComponents.svc/GetLayoutData/:bundlename", { bundlename: "#bundlename" },
{
GetData: { method: "GET", params: {}, isArray: false },
GetDataById: { method: "GET", params: { bundlename: "Iotasol" }, isArray: false }
});
return src;
});
function LayoutController($scope, masterResource) {
$scope.LayoutBean = masterResource.GetDataById();
}
Now i want to specify full url of service like:
http://www.abc.com/BundleService/BundleComponents.svc/GetLayoutData/:bundlename
instead of:
../BundleService/BundleComponents.svc/GetLayoutData/:bundlename
Can any one tell me how can I pass full url of service dynamically

Resources