houman_ag
houman_ag

Reputation: 237

How to use Model data inside javascript code?

In my View (asp.net) code, I am simply displaying a bunch of checkboxes. Whenever one of them is clicked, the following java script code is called (which I found in another stackoverflow question):

var RatingClicked = function (rate) {
    //some initial work goes here

    $.ajax({
        url: '@Url.Action("SetRate","Home")',
        data: { SelectedRate: rate},
        success: function (data) {
            //call is successfully completed and we got result in data

        },
        error: function (xhr, ajaxOptions, thrownError) {
            //some errror, some show err msg to user and log the error
            alert(xhr.responseText);

        }
    });
}

So far so good. The code works as expected and my SetRate action method gets called passing the right data (i.e. rate, which is the value of the check box). The problem is that I need to pass some other data in addition to "rate" which are my view's model info. However, as soon as I change the line of code to the following, javascript seems to stop working altogether:

        data: { SelectedRate: rate, SomeOtherData:@Model.MyData},

I understand that javascript runs on the client-side vs razor's server side run. But what would be the workaround? How can I call my SetRate action method passing the correct values?

Edit: here is all I have inside my view (aside from a couple of other javascript functions)

@using Impoware.Models
@model HomeViewModel

<input type="checkbox" value="1" id="Rating1" onclick="RatingClicked(1)" onmouseover="MouseOverRating(1)" onmouseout="MouseOutRating(1)" />
<input type="checkbox" value="2" id="Rating2" onclick="RatingClicked(2)" onmouseover="MouseOverRating(2)" onmouseout="MouseOutRating(2)" />
<input type="checkbox" value="3" id="Rating3" onclick="RatingClicked(3)" onmouseover="MouseOverRating(3)" onmouseout="MouseOutRating(3)" />
<input type="checkbox" value="4" id="Rating4" onclick="RatingClicked(4)" onmouseover="MouseOverRating(4)" onmouseout="MouseOutRating(4)" />
<input type="checkbox" value="5" id="Rating5" onclick="RatingClicked(5)" onmouseover="MouseOverRating(5)" onmouseout="MouseOutRating(5)" />

Edit 2: I changed the code as Shyju suggests below and it worked for the primary data types (int, bool, etc.) However, when I tried to pass in my whole data Model, I got the following error:

An exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll but was not handled in user code

Additional information: Self referencing loop detected with type 'System.Data.Entity.DynamicProxies.UserParticipation_D381F3E084EC9A0B56FA60725061B956AEF865280516092D8BDE683C9A32725B'. Path 'userParticipation.AspNetUser.UserParticipations'.

UserParticipation is a class that has a foreign key connecting to AspNetUser (many to 1 relationship). The model was created using EntityFramework. Why would there be a loop back to UserParticipation? Oh and lastly, I am passing back the whole Model data in order to save some trips to the database again to re-retrieve the same data for the trip back to the same View (if that makes any sense).

Upvotes: 2

Views: 2393

Answers (2)

Banners
Banners

Reputation: 247

Did you want something a bit more dynamic like this?

<% foreach( var item in Model.Items )     { %>

<input type="checkbox" value="@item.value" onclick="RatingClicked(@item.value,@item.value2)   /> 

<% } %>



var RatingClicked = function (rate,otherValue) {
......

Upvotes: 0

Shyju
Shyju

Reputation: 218892

You can use JsonConvert.SerializeObject method to get a serialized string version of your C# Model/Model property.

This should work.

var myData = { SelectedRate: rate, 
     SomeOtherData: @Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model.MyData)) };
console.log(myData);

 //Use myData variable for the ajax call now.

Also, since it is a complex js object, you should stringify this js object and send that in your ajax call. Make sure you are explicitly specifying "application/json" as the contentType so that model binding will not fail. You may also consider doing a HttpPost ajax call as GET use querystring to send data and querystring has limitations on how much data you can send(varies in browsers)

$.ajax({
        url: '@Url.Action("SetRate","Home")',
        type:'POST',
        data: JSON.stringify(myData),
        contentType : "application/json",        
        success: function (data) {
            //call is successfully completed and we got result in data

        },
        error: function (xhr, ajaxOptions, thrownError) {
            //some errror, some show err msg to user and log the error
            alert(xhr.responseText);

        }
});

While this answers your question, You should double check why you want to send the entire data back ? May be send a unique Id from which your server method will be able to reconstruct the model/specific data as needed

Upvotes: 2

Related Questions