MVC: Get URL of Method When Using Routing - javascript

I found this tutorial on how to build cascading dropdowns in MVC with Razor syntax. I followed the tutorial and got it working perfectly in it's own project. But now that I am trying to port it over to my actual project, I am getting an error when the first dropdown is changed. As per the script, an alert pops up that says:
Failed to retrieve states: [object Object]
I have no idea what [object Object] means. My guess is that the error has something to do with the Url:
url: '#Url.Action("GetStates")
But that's just a guess. The major difference between the example project and the real project is that the real project uses routing for the URL Here's the entire script:
<script src="~/Scripts/jquery-1.10.2.js" type="text/javascript"></script>
<script src="~/Scripts/jquery-1.10.2.min.js" type="text/javascript"</script>
<script type="text/javascript">
$(document).ready(function () {
//Dropdownlist Selectedchange event
$("#Country").change(function () {
$("#State").empty();
$.ajax({
type: 'POST',
url: '#Url.Action("GetStates")', // we are calling json method
dataType: 'json',
data: { id: $("#Country").val() },
// here we are get value of selected country and passing same value as input to json method GetStates.
success: function (states) {
// states contains the JSON formatted list
// of states passed from the controller
$.each(states, function (i, state) {
$("#State").append('<option value="' + state.Value + '">' +
state.Text + '</option>');
// here we are adding option for States
});
},
error: function (ex) {
alert('Failed to retrieve states: ' + ex);
}
});
return false;
})
});
EDIT AFTER:
While watching the network traffic in Chrome's developer tools, I did this in the stand-alone project that works, and saw this entry with the title "GetStates" and this URL: http://localhost:50266/CustomerFeedback/GetStates.
I did it again in my actual project, and this time I see an entry that says "45/" with this URL: http://localhost:65303/PatientSatisfactionSurvey/45/.
I think this confirms my suspicion that the URL is the problem. I'm going to have to play around with figuring out how to make this URL valid.
Another Edit:
On the project that works, if I go to: http://localhost:50266/CustomerFeedback/GetStates
I get this:
Server Error in '/' Application.
This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet.
This is expected as I am trying to hit that actual method. Meaning, I can go to the URL of the method. But when I try and do the same thing in my project: http://localhost:65303/PatientSatisfactionSurvey/GetStates, it just loads the page. That's because it thinks that "GetStates" is a parameter, and not a method.
I CAN NOT figure out what the URL of the method would be!! The dang routing is getting in the way....
routes.MapRoute(
"PatientSatisfactionSurvey",
"PatientSatisfactionSurvey/{ApptID}/{*LanguageCode}",
new { controller = "Forms", action = "PatientSatisfactionSurvey" },
namespaces: new[] { "GEDC.Controllers" }
);

Try changing #Url.Action("GetStates") to:
#Url.Action("ControllerName", "ActionName")
Probbaly something like #Url.Action("PatientSatisfactionSurvey", "GetStates")
which will generate a URL like ~/PatientSatisfactionSurvey/GetStates/5 where 5 is the ID that it is grabbing from the html element with the ID of Country.

Finally worked this out. My problem was three fold. First, when I looked at the HTML source, it turned out this:
url: '#Url.Action("GetStates")', // we are calling json method
was rendering as this:
url: ''
Once I took out the razor syntax, it at least rendered properly in HTML. However, it was still getting the wrong URL. Because the route map I was using had parameters in it, I ended up just creating a whole new route map for this one method:
routes.MapRoute(
"GetStates",
"GetStates",
new { controller = "Forms", action = "GetStates" },
namespaces: new[] { "xyz.Controllers" }
);
Then I changed the URL line in the javascript to look like this:
url: 'GetStates'
But the problem with this was that it was just appending /GetStates to the end of whatever URL I happened to be on. If put the entire fully qualified URL in there, like this...
url: 'http://localhost:65303/GetStates'
That worked. But for obvious reasons, that URL is not a long term solution. So, using this thread, I finally found the answer. I was able to get the fully qualified URL of this method GetStates() as follows:
// Get the fully qualifed URL of the FollowUpOptions() method for use in building the cascading dropdown
UrlHelper Url = new UrlHelper(System.Web.HttpContext.Current.Request.RequestContext);
myModel.ullDropdownUrl = Url.Action("GetStates", "Forms", new { }, this.Request.Url.Scheme);
Then I was able to do this in the javascript, which FINALLY got it all working:
url: '#Model.fullDropdownUrl'

Related

JQuery - Ajax get Request - doesn't return me the "extracts" or "exintro" (summary) property in the response

In general I'm working on a little webapp that just shows me search entries from wikipedia on the page after I enter a search term into the textfield.
I’m working on this problem a long time now.
I have setup an ajax get request to the wikipedia api.
It’s working fine as far as the title goes. But I looked at the json I get in return via console.log and see that there is no summary or first paragraph in this response.
So I googled and found a very nice article which points me to that link:
(can't post it due to under 10 reputation, sad story)
Just google for "wikipedia extracts api"
It says that the query also needs this prop=“extracts” and the exintro: true
But if I add this to my query I do not get the "exintro" in return.
Here is how I set up my ajax call:
function callback(){ // gets called when sliding up the div is completed
$.ajax({
url: 'http://en.wikipedia.org/w/api.php',
//TODO: Fix this line of code (extracts)
data: { action: 'query', list: 'search', prop: 'extracts', exintro: true, srsearch: $("input[name=search]").val(), format: 'json' },
dataType: 'jsonp',
success: processResult
});
$(".container").remove();
}
So if it’s successfull it runs the processResultmethod:
function processResult(apiResult){
console.log(apiResult);
for (var i = 0; i < apiResult.query.search.length; i++){
$('#display-result').append('<div class="' + i + '">' + '<p>'+apiResult.query.search[i].title+'</p>' + '<p>'+ apiResult.query.search[i].snippet +'</p>' + '</div>');
}
}
But the json it returns looks something like that:
Picture of the returned json
Nothing I’m interested in. I need the summary or exintro how wiki api calls this.
Here is the link to the github: https://github.com/dhuber666/wikipediaJS
Any ideas? Do I set it up wrong in the ajax call object “data” ? Pleae help!
The snippetin the json is useless since it cuts off the sentence after a few words
Your "data" object is fine. Seems like "snippet" is just what Wikimedia API returns for this request. You can then send request to get extracts of returned pages (using "title" or "pageid" you get for each article). For example: https://en.wikipedia.org/w/api.php?format=json&action=query&prop=extracts&exintro=true&explaintext=true&titles=Title|Hello for titles "Title" and "Hello".
Maybe this other API call will suit your needs:
https://en.wikipedia.org/w/api.php?action=opensearch&search=hello&format=json It returns one full sentence, doesn't cut anything.

What is state Id that xtext uses while saving the resource

I am hosting xtext's orion editor using iframe in my angular application. I need to save the content written from my angular application side to a backend (Java application). Can anyone help me with what API calls or approach should I make from my angular side so that I can save the content written in the editor.
What I have already done :
1 .I tried extracting the content from the iframe from my angular side , but the data so extracted is partial as it only extracts data what is only visible through the iframe at once and not the whole content which one has to scroll to view .
2 . I tried making 'save' API calls that the xtext makes while saving, but it requires some stateId as its request body . I need to understand what is this state Id and how is it evaluated ?
I am making this call from my angular application
_this.saveEditor = function(args) {
var params = {
requiredStateId: args.stateId
}
_this.saveUrl = XTEXT_URL + '/save?resource=' + args.resourceId;
return $http({
method: 'POST',
url: _this.saveUrl,
data: params
});
};
my request body is :
{"requiredStateId":"-80000000"}
And this is the state Id i am obtaining by making a prior load api call which.returns state Id in its response.
may this snipped can help you, i dont know how you can wire this up with your stuff though
require(["orion/code_edit/built-codeEdit-amd"], function() {
require(["xtext/xtext-orion"], function(xtext) {
var editors = xtext.createEditor({
baseUrl: baseUrl,
syntaxDefinition: "xtext-resources/generated/mydsl-syntax"
}).done(function(editorViewer) {
$("#save-button").click(function() {
editorViewer.xtextServices.saveResource();
});
$("#log-button").click(function() {
console.log(editorViewer.xtextServices.editorContext.getServerState());
});
});
});
});
where i do the simple log you can query and then call save manually.

Correct jQuery syntax for doing a $.post with a header (ASP.NET MVC)

I'm working on a ASP.NET MVC project that uses some jQuery on the client side. I have a jQuery call like this, which works correctly:
$.post($('form').attr("action"), $('form').serialize(), function(data){
// Deal with the data that came back from the ASP.NET MVC controller
}
I want to do the exact same call, except I also want to send in a custom header. I am able to successfully create and send a custom header like this:
var token = $('input[name="__RequestVerificationToken"]').val();
var headers = {};
headers['__RequestVerificationToken'] = token;
$.ajax({
url: "/report_observation/" + submitType,
cache: false,
type: "POST",
data: {
'viewModel': $('form').serialize(),
},
headers: headers,
success: function (data) {
// Deal with the data that came back from the ASP.NET MVC controller
},
error: function (response) {
alert("Error: " + response);
}
});
There are two problems with this second bit of code. One is that I have to make a custom url to go to the correct controller, and I don't know of a way to simply use $('form').attr("action") to automatically go to the correct place.
The second -- and bigger -- problem is that I'm not able to pass over the form data with $('form').serialize() as I could in the one liner $.post example. Doing a #Html.Raw(Json.Encode(Model)) in my Razor cshtml file doesn't send over the model for the whole form, presumably because this code is within a partial view that doesn't know the state of the models in the other partial views that make up this form.
Anyway, I'm thinking there must be an easy way to take this code...
var token = $('input[name="__RequestVerificationToken"]').val();
var headers = {};
headers['__RequestVerificationToken'] = token;
...and incorporate the headers property into this bit of code:
$.post($('form').attr("action"), $('form').serialize(), function(data){
// Deal with the data that came back from the ASP.NET MVC controller
}
However, I can't figure out the correct syntax. Any ideas?
OK, I figured it out. The second example can indeed work if the data field looks like this:
data: $("form").serialize(),
In other words, I had to NOT assign it to the viewModel parameter.
yes, for the second problem use that dev5000 says, and, for the URL, simply get the value for the attribute action fo the form and use it:
var url = $("from").attr("action");
$.ajax({
url: url,
...
})

backbone model fetch JSON element by ID

I am using backbone for the first time and I am really struggling to get it to function correctly with a JSON data file.
I have a model Like so:
window.Test = Backbone.Model.extend({
defaults: {
id: null,
name: null,
},
url: function() {
return 'json/test.json/this.id';
},
initialize: function(){
}
});
When a test item is clicked I then try to bring up the details of the pacific model that was clicked by doing
testDetails: function (id) {
var test = new Test();
test.id = id;
test.fetch({ success: function(data) { alert(JSON.stringify(data))}});
},
However this does not work, I am unable to correctly say "get the JSON element with the passed ID"
Can anyone please show me how to correctly structure the models URL to pull the element with the ID.
Thanks
The problem here is that you're treating your JSON data file like a call to a server. That won't work and it's the reason you're getting a 404. If you're accessing a file locally, you have to load the file first. You can do this with jQuery using the .getJSON() method, or if the file's static, just load it into memory with a script block (though you'll probably need to assign a var in the file). Most likely, you'll use jQuery. An example of this can be found here:
Using Jquery to get JSON objects from local file.
If this is an array of JSON, you can load the array into a collection, and use the "at" method to access the particular element by id. If it's entirely JSON, you'll have to create a custom parser.
your url is incorrect for one. you are returning the literal string 'this.id'. you probably want to do something more along the lines of
url: function () {
return 'json/test.json/' + this.id;
}
I would start by fixing your url function:
url: function() {
return 'json/test.json/' + this.get('id');
}
The way you have it now, every fetch request, regardless of the model's id, is going to /json/test.json/test.id

How to pass data from one HTML page to another HTML page using JQuery?

I have two HTML pages that work in a parent-child relationship in this way:
The first one has a button which does two things: First it requests data from the database via an AJAX call. Second it directs the user to the next page with the requested data, which will be handled by JavaScript to populate the second page.
I can already obtain the data via an ajax call and put it in a JSON array:
$.ajax({
type: "POST",
url: get_data_from_database_url,
async:false,
data: params,
success: function(json)
{
json_send_my_data(json);
}
});
function json_send_my_data(json)
{
//pass the json object to the other page and load it
}
I assume that on the second page, a "document ready" JavaScript function can easily handle the capture of the passed JSON object with all the data. The best way to test that it works is for me to use alert("My data: " + json.my_data.first_name); within the document ready function to see if the JSON object has been properly passed.
I simply don't know a trusted true way to do this. I have read the forums and I know the basics of using window.location.url to load the second page, but passing the data is another story altogether.
session cookie may solve your problem.
On the second page you can print directly within the cookies with Server-Script tag or site document.cookie
And in the following section converting Cookies in Json again
How about?
Warning: This will only work for single-page-templates, where each pseudo-page has it's own HTML document.
You can pass data between pages by using the $.mobile.changePage() function manually instead of letting jQuery Mobile call it for your links:
$(document).delegate('.ui-page', 'pageinit', function () {
$(this).find('a').bind('click', function () {
$.mobile.changePage(this.href, {
reloadPage : true,
type : 'post',
data : { myKey : 'myVal' }
});
return false;
});
});
Here is the documentation for this: http://jquerymobile.com/demos/1.1.1/docs/api/methods.html
You can simply store your data in a variable for the next page as well. This is possible because jQuery Mobile pages exist in the same DOM since they are brought into the DOM via AJAX. Here is an answer I posted about this not too long ago: jQuery Moblie: passing parameters and dynamically load the content of a page
Disclaimer: This is terrible, but here goes:
First, you will need this function (I coded this a while back). Details here: http://refactor.blog.com/2012/07/13/porting-javas-getparametermap-functionality-to-pure-javascript/
It converts request parameters to a json representation.
function getParameterMap () {
if (window.location.href.indexOf('?') === (-1)) {
return {};
}
var qparts = window.location.href.split('?')[1].split('&'),
qmap = {};
qparts.map(function (part) {
var kvPair = part.split('='),
key = decodeURIComponent(kvPair[0]),
value = kvPair[1];
//handle params that lack a value: e.g. &delayed=
qmap[key] = (!value) ? '' : decodeURIComponent(value);
});
return qmap;
}
Next, inside your success handler function:
success: function(json) {
//please really convert the server response to a json
//I don't see you instructing jQuery to do that yet!
//handleAs: 'json'
var qstring = '?';
for(key in json) {
qstring += '&' + key + '=' + json[key];
qstring = qstring.substr(1); //removing the first redundant &
}
var urlTarget = 'abc.html';
var urlTargetWithParams = urlTarget + qstring;
//will go to abc.html?key1=value1&key2=value2&key2=value2...
window.location.href = urlTargetWithParams;
}
On the next page, call getParameterMap.
var jsonRebuilt = getParameterMap();
//use jsonRebuilt
Hope this helps (some extra statements are there to make things very obvious). (And remember, this is most likely a wrong way of doing it, as people have pointed out).
Here is my post about communicating between two html pages, it is pure javascript and it uses cookies:
Javascript communication between browser tabs/windows
you could reuse the code there to send messages from one page to another.
The code uses polling to get the data, you could set the polling time for your needs.
You have two options I think.
1) Use cookies - But they have size limitations.
2) Use HTML5 web storage.
The next most secure, reliable and feasible way is to use server side code.

Categories

Resources