Pass data to controller using jQuery

We want to pass some data from jQuery to ASP.NET Core / MVC. We have an action method “AddEmployee” in Home controller and we want to pass input values to the controller.

$(document).ready(function () {
        $("#btnSave").click(function () {
            var formData = new FormData();
            //Reading text box values using Jquery)
            formData.append('Name', $("#txtName").val(); 
            formData.append('City',$("#txtAddress").val());
            formData.append('Address',$("#txtcity").val());
            $.ajax(
            {
                type: "POST", //HTTP POST Method
                url: "Home/AddEmployee", // Controller/View 
                //url: '@Url.Action("AddEmployee", "Home")',
                data: { //Passing data
                    formData
                },
                //cache: false,
                //processData: false,
                //contentType: false,

                success: function (data) {
                    alert("success...any incoming data");
                },
                failure: function (data) {
                    alert("failure....");
                }
            });
        });
    });

Alternatively we can have seperate functions for success and failure actions;

function btnSaveSuccess(data)
{
  alert('success');
}

function btnSaveFailure(data)
{
  alert('failure');
}

We can call these functions in btnSave main function sucess/failure blocks.

To work with jQuery we need to reference of jQuery library .You can use following CDN jQuery libraryfrom any provider such as Microsoft,Google or jQuery .

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> 

To use jQuery library you need an active internet connection , You can download and use it as offline .You need to be add reference as like below.

<script src="~/Scripts/jquery-1.10.2.min.js"></script>

Access to XMLHttpRequest from origin has been blocked by CORS policy…

I did a Web API deployment in Azure Web API service. I was able to access the URL in browser and Postman. I started getting following error when I try to integrate in ASP.NET Web App in my local development environment;

Access to XMLHttpRequest at ‘https://xyz-dev.azurewebsites.net/api/Authentication/GetTestUser?name=testuser’ from origin ‘http://localhost:17686’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

jquery.js:9172          GET https://xyz-dev.azurewebsites.net/api/Authentication/GetTestUser?name=testuser net::ERR_FAILED

To solve the problem, I did this;

Here is server-side (Web API) code;

Add following to Web API ConfigureServices method;

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(op =>
    {
       op.AddPolicy("AllOrigin", builder => builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
    });
}

Add following to Web API Configure method;

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
{
      //-------use cords
      app.UseCors("AllOrigin");
}

Here is client-side AJAX call.

<input type="button" id="btnWebApiCall" name=" btnWebApiCall" value="Test CORS" class=" btn btn-primary btn-lg justify-content-center" />

@section Scripts
    {

    <script>

        $(document).ready(function () {

            $("#btnAuthenticateSSO").click(function (e) {
                e.preventDefault();
                $.ajax({
                    type: "GET",
                    url: "https://xyzapi-dev.azurewebsites.net/api/Authentication/GetTestUser?name=testuser",
                    contentType: "application/json; charset=utf-8",
                    //crossDomain: true,
                    dataType: "json",
                    success: function (data, status, xhr) {
                        alert(JSON.stringify(data));
                        console.log(data);
                    }, //End of AJAX Success function
                    error: function (xhr, status, error) {
                        alert("Result: " + status + " " + error + " " + xhr.status + " " + xhr.statusText);
                    } //End of AJAX error function

                });
            });

        });

    </script>

}

The pain is gone.

If interested in learning more about this, read below;

Researched and figured out that browser sends two requests to the server. Tiny request and actual request.

The browser sends a tiny request called a preflight request before the actual request. It includes details such as the HTTP method used and whether any custom HTTP headers are present. The preflight allows the server to see how the actual request would appear before it is sent. The server will then tell the browser whether or not to submit the request, or whether to return an error to the client instead.

See below for problem header without CORS and with CORS in web API;

Headers without CORS implementation in Web API (Problem);

Headers with CORS implementation in Web API (Problem solved);

A simple Get request make these two requests;

Resources

https://medium.com/easyread/enabling-cors-in-asp-net-web-api-4be930f97a5c

https://stackoverflow.com/questions/31942037/how-to-enable-cors-in-asp-net-core

JavaScript frequently used functions

This is a handy reference for frequently used JavaScript functions;

Shorten the console log

Instead of writing console.log() again and again in code, we can bind it;

//tired of typeing console.log. shorten it
    const log = console.log.bind(document);
    log("does it works?");
    log("yes");

Merge two arrays into one

If you want to merge two arrays of any size into a single array you can use the concate JavaScript function.

//merge two arrays
    const array1 = ["one", "two", "three"]
    const array2 = ["four", "five", "six"]

    const merged = array1.concat(array2)
    console.log(merged)
    //Output:
    //(6) ['one', 'two', 'three', 'four', 'five', 'six']

Merge two objects into one

If you working with objects you can merge them together with this simple trick.

//merge two objects into one
    const user = {
        name: "Shahzad",
        gender: "Male"
    };
    const artcile = {
        title: "Born on the Fourth of July",
        publishDate: "12/14/2021"
    };
    const summary = {...user, ...artcile}
    console.log(summary)
    //Output:
    /*
    gender: "Male"
    name: "Shahzad"
    publishDate: "12/14/2021"
    title: "Born on the Fourth of July"
    */

Shorten an array

There exist an easy way for web developers to shorten an array. You need to use the length method and pass a number that is smaller than the actual array size.

//shorten an array
    const big_array = ["one", "two", "three", "four", "five", "six"]
    big_array.length = 3
    console.log(big_array)
    //Output:
    //(3) ['one', 'two', 'three']

Shuffle an array

Sometimes you want to randomize the values within an array. To achieve this you can use the Array.sort function with a random compareFunction.

//shuffle an array
    const array = ["one", "two", "three", "four", "five", "six"]
    array.sort( function(){ return Math.random() - 0.5})
    console.log('shuffling array')
    console.log(array)

Use isNum to verify a number

With this function, you can check whether a value or variable is a number (int, float, etc) or not.

//use isNum to verify Number
    function isNum(n) {return !isNaN(parseFloat(n)) && isFinite(n);}

    console.log(isNum(4125))        //true
    console.log(isNum(50))          //true
    console.log(isNum("jQuery"))    //false

Use isStr to verify a string

With this function, you can check whether a value or variable is in string format or not.

//use isStr to verify string
    const isStr = value => typeof value === 'string';

    console.log(isStr("jQuery"))    //true
    console.log(isStr(4125))        //false
    console.log(isStr(true))        //false

Use isNull

Often it is useful to check if a result or data is null.

//use isNull
    const isNull = value => value == null || value === undefined;

    console.log(isNull(null))   //true
    console.log(isNull())       //true
    console.log(isNull(123))    //false
    console.log(isNull("s"))    //false

Calculate the performance of a function

If you want to check how long a function runs you can use this approach in your program.

//Calculate the performance of a function
    const start = performance.now();
    //business program
    const end = performance.now();
    const total = start - end
    console.log("function takes " + total + " milisecond");

Remove duplicates from an array

We often encounter an array with duplicated data in it and use a loop to remove those duplicates. This function can remove duplicates in an easy way without using a loop.

//Remove duplicates from an array
    const duplicate_array = array => [...new Set(array)]
    console.log(duplicate_array([
        "One", "Two", "Three", "Two", "Four",
        "One", "Two", "Three", "Two", "Five",
        "Three", "One", "Four", "Two", "Five"]))

    //Output:
    //(5) ['One', 'Two', 'Three', 'Four', 'Five']

Use logical AND/OR for conditions

Instead of using an if-condition, you can use a logical AND/OR. This can be used within a function for executing commands.

//Use logical AND/OR for conditions
    const input = 2
    input == 4 && console.log("it is 4")
    input == 4 || console.log("it is not 4")

    //can also be used for assigning values
    function defaultTo4(arg) {
        arg = arg || 4; //arg will have 4 as a default value if not set
        console.log(arg)
    }
    let arg1 = 2
    let arg2 = null
    defaultTo4(arg1)    //2
    defaultTo4(arg2)    //4

Ternary operator

The ternary operator is just cool. You can avoid bad-looking nested conditional if..elseif..elseif with ternary operators.

//Ternary operator
    function temperature(temp){
        return (temp > 39 || temp < 35.5) ? 'Stay home'
        : (temp < 37.5 && temp > 36.5) ? 'Go out and play'
        : (temp <= 39 && temp >= 35.5) ? 'Take some rest'
        : ''
    }

    console.log(temperature(38))    //take some rest
    console.log(temperature(36))    //take some rest
    console.log(temperature(39.1))  //Stay home
    console.log(temperature(35.1))  //Stay home
    console.log(temperature(37))    //Go out and plan

Resources

https://docs.microsoft.com/en-us/javascript/

Get base url in javascript

If you are constructing your URL like this;

message += '<br><a href=/Project/GetFileData?documentId=' + response.Data.vm.DocumentId + '>' + response.Data.vm.FileName + '</a>';

You will get results like this;

https://www.foo.com/Project/GetFileData?1234

This will not work on a web site that has following URL;

https://www.foo.com/demo/Project/GetFileData?1234

To fix this problem in ASP.NET Core, use this;

var url = '@Url.Content("~");
message += '<br><a href=' + url + '/Project/GetFileData?documentId=' + response.Data.vm.DocumentId + '>' + response.Data.vm.FileName + '</a>';

Other useful function to find URL are;

var url = window.location.origin;
var host = window.location.host;
var pathArray = window.location.pathname.split( '/' );

Return a Json Object from another function call

When we try to capture a value from called method we get undefined. The reason is that data hasn’t been fetched yet. Fetch takes some time to make the call and send back the result, and it’s asynchronous, Here is an example;

function getApi() {
  var obj;

  fetch("https://foo.apicode.com/posts/1")
    .then((res) => res.json())
    .then((data) => (obj = data));

  return obj;
}

let x = getApi();
console.log(x);

When we console.log the value, getApi() didn’t finish yet, therefore didn’t set the obj

The fetch method is asynchronous, so obj is undefined because the code is going to the next instruction without waiting the fetch. We can simply use async/await method that is a great way to make asynchronous calls because await will wait for the result before going to the next instruction.

async function getApi() {

      const response = await fetch("https://foo.apicode.com/posts/1")
        
      const obj = await response.json()
      
      return obj;
    }

(async() => {
   let x = await getApi();
   console.log(x);
})()

Resources

https://stackoverflow.com/questions/49432579/await-is-only-valid-in-async-function