Calling web APIs using JavaScript

Posted by HairBomb on Wed, 12 Jan 2022 07:16:52 +0100

In this section, you will add an HTML page that contains a form for creating and managing to-do items. Event handlers are attached to elements on the page. The event handler causes an HTTP request to be made to the operation method of the Web API. The {fetch} function of the Fetch API starts each HTTP request.

The fetch # function returns Promise Object that contains the HTTP Response represented as a Response object. The common pattern is to extract the JSON Response body by calling the JSON Response function on the JSON Response object. JavaScript updates the page with the details of the Web API Response.

The simplest {fetch} call accepts a parameter representing the route. The second parameter, called the init object, is optional. Init is used to configure HTTP requests.

  1. Configure application Provide static files and Enable default file mapping . At startup The following highlighted code is required in the Configure method of CS:

    C # replication
     
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
    
        app.UseDefaultFiles();
        app.UseStaticFiles();
    
        app.UseHttpsRedirection();
    
        app.UseRouting();
    
        app.UseAuthorization();
    
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
    
  2. Create a wwwroot folder in the project root.

  3. Create a css folder in the wwwroot folder.

  4. Create a js folder in the wwwroot folder.

  5. A named index HTML HTML files are added to the wwwroot folder. Index Replace the contents of HTML with the following tags:

    HTML copy
     
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>To-do CRUD</title>
        <link rel="stylesheet" href="css/site.css" />
    </head>
    <body>
        <h1>To-do CRUD</h1>
        <h3>Add</h3>
        <form action="javascript:void(0);" method="POST" onsubmit="addItem()">
            <input type="text" id="add-name" placeholder="New to-do">
            <input type="submit" value="Add">
        </form>
    
        <div id="editForm">
            <h3>Edit</h3>
            <form action="javascript:void(0);" onsubmit="updateItem()">
                <input type="hidden" id="edit-id">
                <input type="checkbox" id="edit-isComplete">
                <input type="text" id="edit-name">
                <input type="submit" value="Save">
                <a onclick="closeInput()" aria-label="Close">&#10006;</a>
            </form>
        </div>
    
        <p id="counter"></p>
    
        <table>
            <tr>
                <th>Is Complete?</th>
                <th>Name</th>
                <th></th>
                <th></th>
            </tr>
            <tbody id="todos"></tbody>
        </table>
    
        <script src="js/site.js" asp-append-version="true"></script>
        <script type="text/javascript">
            getItems();
        </script>
    </body>
    </html>
    
  6. Will be named site Add CSS files for CSS to the wwwroot/css folder. Add site JS is replaced with the following type:

    css replication
     
    input[type='submit'], button, [aria-label] {
        cursor: pointer;
    }
    
    #editForm {
        display: none;
    }
    
    table {
        font-family: Arial, sans-serif;
        border: 1px solid;
        border-collapse: collapse;
    }
    
    th {
        background-color: #f8f8f8;
        padding: 5px;
    }
    
    td {
        border: 1px solid;
        padding: 5px;
    }
    
  7. A named site JS to the wwwroot/js folder. Add site JS is replaced by the following code:

    Javascript copy
     
    const uri = 'api/todoitems';
    let todos = [];
    
    function getItems() {
      fetch(uri)
        .then(response => response.json())
        .then(data => _displayItems(data))
        .catch(error => console.error('Unable to get items.', error));
    }
    
    function addItem() {
      const addNameTextbox = document.getElementById('add-name');
    
      const item = {
        isComplete: false,
        name: addNameTextbox.value.trim()
      };
    
      fetch(uri, {
        method: 'POST',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(item)
      })
        .then(response => response.json())
        .then(() => {
          getItems();
          addNameTextbox.value = '';
        })
        .catch(error => console.error('Unable to add item.', error));
    }
    
    function deleteItem(id) {
      fetch(`${uri}/${id}`, {
        method: 'DELETE'
      })
      .then(() => getItems())
      .catch(error => console.error('Unable to delete item.', error));
    }
    
    function displayEditForm(id) {
      const item = todos.find(item => item.id === id);
      
      document.getElementById('edit-name').value = item.name;
      document.getElementById('edit-id').value = item.id;
      document.getElementById('edit-isComplete').checked = item.isComplete;
      document.getElementById('editForm').style.display = 'block';
    }
    
    function updateItem() {
      const itemId = document.getElementById('edit-id').value;
      const item = {
        id: parseInt(itemId, 10),
        isComplete: document.getElementById('edit-isComplete').checked,
        name: document.getElementById('edit-name').value.trim()
      };
    
      fetch(`${uri}/${itemId}`, {
        method: 'PUT',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(item)
      })
      .then(() => getItems())
      .catch(error => console.error('Unable to update item.', error));
    
      closeInput();
    
      return false;
    }
    
    function closeInput() {
      document.getElementById('editForm').style.display = 'none';
    }
    
    function _displayCount(itemCount) {
      const name = (itemCount === 1) ? 'to-do' : 'to-dos';
    
      document.getElementById('counter').innerText = `${itemCount} ${name}`;
    }
    
    function _displayItems(data) {
      const tBody = document.getElementById('todos');
      tBody.innerHTML = '';
    
      _displayCount(data.length);
    
      const button = document.createElement('button');
    
      data.forEach(item => {
        let isCompleteCheckbox = document.createElement('input');
        isCompleteCheckbox.type = 'checkbox';
        isCompleteCheckbox.disabled = true;
        isCompleteCheckbox.checked = item.isComplete;
    
        let editButton = button.cloneNode(false);
        editButton.innerText = 'Edit';
        editButton.setAttribute('onclick', `displayEditForm(${item.id})`);
    
        let deleteButton = button.cloneNode(false);
        deleteButton.innerText = 'Delete';
        deleteButton.setAttribute('onclick', `deleteItem(${item.id})`);
    
        let tr = tBody.insertRow();
        
        let td1 = tr.insertCell(0);
        td1.appendChild(isCompleteCheckbox);
    
        let td2 = tr.insertCell(1);
        let textNode = document.createTextNode(item.name);
        td2.appendChild(textNode);
    
        let td3 = tr.insertCell(2);
        td3.appendChild(editButton);
    
        let td4 = tr.insertCell(3);
        td4.appendChild(deleteButton);
      });
    
      todos = data;
    }
    

You may need to change ASP Net core project startup settings for local testing of HTML pages:

  1. Open properties \ launchsettings json.
  2. Delete launchUrl so that it can be found in the project's default file index HTML force open application.

This example calls all CRUD methods of the Web API. The following describes the Web API request.

Get a list of to DOS

In the following code, send the HTTP GET request to the api/todoitems route:

Javascript copy
 
fetch(uri)
  .then(response => response.json())
  .then(data => _displayItems(data))
  .catch(error => console.error('Unable to get items.', error));

Called when the Web API returns code with a success status_ displayItems() function. Will_ Each to-do in the array parameters accepted by displayItems , is added to the table with edit and delete buttons. If the Web API request fails, an error is logged to the browser's console.

Add to do

In the following code:

  • Declare the {item} variable to construct the object literal representation of the to-do.
  • Use the following options to configure extraction requests:
    • method - specifies the POST HTTP operation verb.
    • Body - specifies the JSON representation of the request body. By passing the object text stored in {item} to JSON.stringify Function to generate JSON.
    • Headers - specifies the HTTP request headers of {Accept} and {content type}. Set both headers to application/json to specify the media types to receive and send, respectively.
  • Send the HTTP POST request to the api/todoitems route.
Javascript copy
 
function addItem() {
  const addNameTextbox = document.getElementById('add-name');

  const item = {
    isComplete: false,
    name: addNameTextbox.value.trim()
  };

  fetch(uri, {
    method: 'POST',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(item)
  })
    .then(response => response.json())
    .then(() => {
      getItems();
      addNameTextbox.value = '';
    })
    .catch(error => console.error('Unable to add item.', error));
}

When the Web API returns the code in the success status, the getItems function is called to update the HTML table. If the Web API request fails, an error is logged to the browser's console.

Update to DOS

Updating a to-do is similar to adding a to-do; However, there are two major differences:

  • The suffix of the route is the unique identifier of the item to be updated. For example, api/todoitems/1.
  • As shown by the method option, the HTTP operation predicate is PUT.
Javascript copy
 
fetch(`${uri}/${itemId}`, {
  method: 'PUT',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(item)
})
.then(() => getItems())
.catch(error => console.error('Unable to update item.', error));

Delete to-do

To DELETE a to-do, set the {method} option of the request to {DELETE} and specify the unique identifier of the item in the URL.

Javascript copy
 
fetch(`${uri}/${id}`, {
  method: 'DELETE'
})
.then(() => getItems())
.catch(error => console.error('Unable to delete item.', error));

Topics: .NET