Wednesday, October 16, 2019

Axios In Action

We all know that Axios is a promise-based HTTP client for the browser and node.js. Although I have used Axios extensively while making GET, POST request calls and multiple concurrent requests call from the front end, I have never used Axios in conjunction with node.js. Today we would be discussing how to use Axios for making any kind of calls from the front end and some other Axios related important stuff.

1. Introduction


Similar to traditional AJAX call, one could easily make Axios calls without much hustle from the front end. One needs to include below JS library in order to work it properly:
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
Today we would be touching on below items:
  • How to make Axios GET / POST calls?
  • How to make multiple concurrent requests calls?
  • How to handle the dependent request calls using Axios?
  • Understanding the response to a request
  • How to handle errors that occurred while making Axios calls?

2. GET Request


Performing a GET request:
// Make a request for a user with a given ID
axios.get('/getAssignment?id=12345')
  .then(function (response) { // handle success
    console.log(response);
  })
  .catch(function (error) {  // handle error
    console.log(error);
  })
  .finally(function () {  // always executed
   ...
  });
Optionally the above request could also be done as
axios.get('/getAssignment', {
    params: {
      id: 12345
    }
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  })
  .then(function () {
    // always executed
  });  

3. POST Request


Performing a POST request:
axios.post('/saveAssignment', {
   'assignmentData' : assignmentData // an array containing: label,type,availableon,dueon etc
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });
Obviously, @RequestMapping i.e. /saveAssignment would call one of our Controller's methods. Worried about how this data would be available in Controller layers? Don't worry? We got you covered here. Just look at the below code snippet:
@RequestMapping(value = "/saveAssignment", headers = "Content-Type=application/json", method = RequestMethod.POST)
@PreAuthorize("isAuthenticated()")
public ResponseEntity<String> saveAssignment(Model model, @RequestBody Map<String, String[]> assignmentDataMap) {

 String[] assignmentData = assignmentDataMap.get("assignmentData");
 ...
} 

4. Multiple concurrent requests


Performing multiple concurrent requests:
function findAssignmentById(assignmentId) {
 return axios.get("/getAssignment?id=" + assignmentId);
}

function findAllAssignmentUser(assignmentId) {
 return axios.get("/getAssignmentUsers?assignmentid=" + assignmentId);
}

axios.all([findAssignmentById(), findAllAssignmentUser()])
  .then(axios.spread(function (assignmentData, userData) {
    // Both requests are now complete
 var assignment = assignmentData.data;
 var users = userData.data;
  }));
Tips: Never use this, when the requests are dependent anyhow.

5. Multiple requests but dependent somehow


It may happen that depending upon the return value from one Axios call, one may require to make another Axios call conditionally. In those cases, one could follow the below approach.
var assignmentId1 = 1234;
axios.get("/getAssignmentUser?id="+assignmentId1).then(function(response) {    
 var assignmentUserFlag = response.data.size() > 0;
 if(assignmentUserFlag){
  axios.get("/getAssignment?id="+assignmentId1).then(function(response) { 
  
  }).catch(function (error) {
   ...
  });
 } else {
   ....
 }
}).catch(function (error) {
 ...
});

6. Understanding the response to a request 


The response to a request contains the following information:
{
  // `data` is the response that was provided by the server
  data: {},
 
  // `status` is the HTTP status code from the server response
  status: 200,
 
  // `statusText` is the HTTP status message from the server response
  statusText: 'OK',
 
  // `headers` the headers that the server responded with
  // All header names are lower cased
  headers: {},
 
  // `config` is the config that was provided to `axios` for the request
  config: {},
 
  // `request` is the request that generated this response
  // It is the last ClientRequest instance in node.js (in redirects)
  // and an XMLHttpRequest instance the browser
  request: {}
}
When using then, one will receive the response as follows:
axios.get('/getAssignment?id=12345')
  .then(function (response) {
    console.log(response.data);
    console.log(response.status);
    console.log(response.statusText);
    console.log(response.headers);
    console.log(response.config);
 });

7. Handling Errors


You must be thinking about why there is a separate section for this. From the start of this article, we have maintained that inside catch block i.e. ".catch(function (error) { ..}" we would handle the error, End of the Story right? But wait there is still more left to it. 
axios.get('/getAssignment?id=12345')
  .catch(function (error) {
    if (error.response) {
      // The request was made and the server responded with a status code
      // that falls out of the range of 2xx
      console.log(error.response.data);
      console.log(error.response.status);
      console.log(error.response.headers);
    } else if (error.request) {
      // The request was made but no response was received
      // `error.request` is an instance of XMLHttpRequest in the browser and an instance of
      // http.ClientRequest in node.js
      console.log(error.request);
    } else {
      // Something happened in setting up the request that triggered an Error
      console.log('Error', error.message);
    }
    console.log(error.config);
  });
Point to ponder: Before starting I would like to highlight that the above code snippet is taken from the official website. It's regarding "else if (error.request) {..}" block. It states that "The request was made but no response was received" obviously from the server. Now one open question to you - In Microservice Architecture, suppose service A is calling service B which is down (we have manually stopped it) then no doubt it would enter in catch block but where would the control go, if, else if or last else block? 
According to me, it should go inside else if block as the server is down(service B) but we have made the request properly. But to my surprise, it entered inside if block. But how can that happen when the server was down? How the server can respond? Just for information, in JS, we are getting Internal Server Error(500 status code) whereas in STS console, 404. If you have the answer to the above question or any logical explanation then please share in the comment section.

8. Conclusion


I hope that now you know how to use Axios. It would surely help you while doing development work using Axios. Happy Learning !! ☺

Friday, October 11, 2019

Download data in CSV format using JavaScript

Today we would be discussing Export to CSV functionality using JavaScript. You might be wondering that there are many 3rd party libraries to generate the CSV file using JavaScript/jQuery then why am I reinventing the wheel? Why don't use the already existing solution? Bear with me, I would not only explain why but also describe how to download data in CSV format using JavaScript?

1. Introduction 


It's the very common use-case that we already have some data on the browser (HTML pages) and we would like to provide the option to users to download these data in CSV format using jQuery / JavaScript. That's why there are many 3rd party libraries in the market to generate the CSV file using jQuery but from the HTML table as the source. Just lookout for a solution that facilitates us to generate the CSV file using jQuery / JavaScript if the current HTML structure representing the data on the page is not in the tabular format. This is where our solution comes in the picture which is very simple and handy. One might argue that it is possible to create a temporary table from the complicated HTML structure on the fly in order to use the 3rd party libraries. But again it depends upon the complexity and we won't be discussing that here. 

2. Browser Compatability 


Tested this utility in below version of the browser and it's working as expected:
  • Google Chrome Version 77.0.3865.90 (64-bit)
  • Firefox Quantum Version 69.0(64-bit)
  • IE 11 Version 11.0.9600.19467

3. Why & Implementation


Now again we would reiterate one which situation and why one should use this Export to CSV utility developed using JavaScript and then directly jump on the implementation.

3.1 Why? 

  • Preferred to use if the current HTML structure is not in tabular format and very complicated  but one could use it even if HTML structure is in tabular format 
  • Handling boundary usecases: Currently if data values have comma then also it properly handles it. 
  • Simple to use
  • Don't have to load any 3rd part library 

3.2 Implementation 


One needs to just create the multi-dimensional data array from the HTML page containing the data using jQuery / JavaScript and then we are good to go. Here for the demo purpose, we have created the multi-dimensional data array manually inside JavaScript. 
<html>
<head>
<title>Download CSV</title>
<script>
// prepare the data from the HTML page using jQuery/JavaScript.
// Demo purpose, we are manually preparing the data
var data = [
   ['Anshul', 'programmer','Gamer'],
   ['Rahul', 'Computer Science Engineer','Traveller'],
   ['Rajnikant', 'Hero','Sky Ga,zing']
];


function downloadCSV() {
    var csv = 'Name,Job,Passion\n';
 
 data.forEach(function(row) {
        var row1 = []; 
        row.forEach(function(item) { // handling commna in data values
        if(item.indexOf(',') == -1) { // not having comma 
    row1.push(item);
  } else {
    item = "\"" + item + "\"";
    row1.push(item);
  }
     });
 console.log("row1:" + row1)
 csv += row1.join(',');
 csv += "\n";
     });
 
 if (navigator.msSaveBlob) { //IE
  var csvURL =  null;
  var csvData = new Blob([csv], {type: 'text/csv;charset=utf-8;'});
                csvURL = navigator.msSaveBlob(csvData, 'download-reports.csv');
 } else { // Firefox,Chrome
         console.log(csv);
  //var hiddenElement = document.createElement('a');
                var hiddenElement = document.getElementById('dummyDownload'); //For Firefox 
  hiddenElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(csv);
  hiddenElement.target = '_blank';
  hiddenElement.download = 'download-reports.csv';
  hiddenElement.click();
    }  
}
</script>
</head>
<body>
<a id=dummyDownload hidden></a> 
<button onclick="downloadCSV()">Download CSV</button> 
</body>
</html>

4. Downloaded CSV File


For reference, showing the downloaded CSV file in both the notepad++ & by Open Office(Separated by option: Comma). See the last row in which, intentionally I have put a comma in one of the data values but our utility properly handles it. 


5. Conclusion


Now you know how to integrate Download CSV functionality in your application which is pretty simple.  Let me know in the comments if it's working for you or not. Happy Learning!! ☺

How to add jQuery datetimepicker in the page?

Today we would be looking at the jQuery datetimepicker implementation. It improves the User Experience. One needs to make a few things in mind for datetimepicker integration like
  • Adding the required HTML code snippet in the page for selecting the date & time i.e. adding input element of type text  
  • Respective JS & CSS libraries(datetimepicker and jQuery related) should be included in the page
  • Activating the datetimepicker using jQuery or JavaScript 
After configuring the datetimepicker, it would look like below:


Implementation:


<html>
<head>
<title>Datetimepicker Demo</title>
<!–– Respective JS & CSS libraries(datetimepicker and jQuery related) should be included in the page ––>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.20/jquery.datetimepicker.min.css" rel="stylesheet"/> 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.20/jquery.datetimepicker.full.min.js"></script>
<script>
$(document).ready(function () {
   // Activating the datetimepicker using jQuery or JavaScript 
   $('#datetimepicker1').datetimepicker(); //default    
   $('#datetimepicker2').datetimepicker({ //customized
      format:'d/m/Y H:i',
      minDate:0,
      formatTime:"h:i a",
      step:10,
      // if one would like to take user selected input from datetimepicker and atomatically round off to nearest integral of 10 minutes
      onChangeDateTime:function(dp,$input){
      //27/10/2019 12:01 -> dateTime[0] = date, dateTime[1] = time
 var dateTime = $input.val().split(" "); 
 var time = dateTime[1].split(":");
 var hour = time[0];
 var minutes = time[1];
 var datetimestring;
    
 if(minutes > 0 && minutes < 10) {
         datetimestring = dateTime[0] + ' ' + hour + ':' + 10;
         $input.val(datetimestring);
  }
    ...
  } // end of onChangeDateTime function
   });
   
});
</script>
</head>
<body>
<!–– Adding the required HTML code snippet in the page for selecting the date & time i.e. adding input element of type text  ––>
Default Datetimepicker:
<input type="text" id="datetimepicker1" placeholder="select date time">
Customized Datetimepicker:
<input type="text" id="datetimepicker2" placeholder="select date time">
</body>
</html>

Hoping that it would help you. Happy Learning!! ☺

Thursday, October 10, 2019

th:block tag in Thymeleaf

While designing and developing a Thymeleaf template, have you ever faced a problem of adding unnecessary HTML tag just for holding any conditional statements or an iterative statement which you won't prefer to use if you design the same page statically? Let me give you an example: using <div> blocks inside <table> for iteration purpose only, it might work but it would add an unnecessary empty HTML tag. Don't worry Thymeleaf has a solution for this type of use case. One could use Thymeleaf's provided Synthetic th:block tag. Today we would be discussing th:block tag with some example.

1. th:block tag


  • It's an element processor included in the Standard Dialects. Don't confuse this with an attribute as it is not an attribute. 
  • It is a mere attribute container that allows template developers to specify whichever attributes they want. Thymeleaf will execute these attributes and then simply make the block disappear without a trace.

2. th:block tag Implementation Examples


There are many instances where one could use th:block tag while designing the Thymeleaf templates. It would make our Thymeleaf templates more readable and helps in avoiding unnecessary empty HTML tags which are added after processing of Thymeleaf's attributes if we don't use th: block. I would be sharing the use cases where I have used it:
  • when creating iterated tables that require more than one <tr> for each element
    Disclaimer: This example reference is taken from here. I haven't used it.
    <table>
      <th:block th:each="user : ${users}">
        <tr>
            <td th:text="${user.login}"></td>
            <td th:text="${user.name}"></td>
        </tr>
        <tr>
            <td colspan="2" th:text="${user.address}"></td>
        </tr>
      </th:block>
    </table>
    
  • when creating the ordered / unordered list of items
    <ul>
       <th:block th:each="node : ${bookModel.getOrderedSubTopics()}">
         <li th:if="${node eq 'activity'}">
     <input th:id="${node.nodeId}" type="checkbox" th:value="${node.nodeId}">
      <span th:utext="${node.label}">Topic Name</span>    
          </li>
          <li th:if="${node eq 'reading'}">
       <span th:utext="${node.label}">Topic Name</span>    
          </li>
       </th:block>
    </ul>
    
  • when creating a select box when dropdown items are selected or unselected conditionally
     <select>
       <option value="0"></option>
       <th:block th:each="tag : ${tags}">
         <option th:text="${tag.label}" th:if="${itemTags.contains(tag)}" th:value="${tag.tagTypeLabel}" selected>name</option>
         <option th:text="${tag.label}" th:if="not ${itemTags.contains(tag)}" th:value="${tag.tagTypeLabel}">name</option>
        </th:block>
    </select>

3. Conclusion


th:block tag is a very useful tool that could be used while designing and development of Thymeleaf templates. Template developers don't have to unnecessarily complicate their template/page by adding an HTML tag for holding Thymeleaf's attributes if they don't want that HTML tag after execution in their HTML structure.  Hoping that it would help you. Happy Learning!! ☺

How to access Spring beans in Thymeleaf registered at the Spring Application Context?

Thymeleaf allows accessing beans registered at the Spring Application Context in the standard way defined by Spring EL i.e. by using the @beanName syntax, for example:
<div th:text="${@urService.getSomething()}">...</div> 
This could be useful if one wants to expose some utility methods from Java end to Thymeleaf templates.

Disclaimer:
Till now I haven't used this feature in any of my projects but when I came to know about this feature. I thought why not test it whether it really works or not.
For testing purposes, I have added a @Component annotation (org.springframework.stereotype.Component;) in one of my Spring Boot Utility Class and added a test method i.e. getMessage() which simply returns a String. The idea is to make this bean available in the Spring Application Context. After that, I have tried accessing it using the above syntax and it worked.
For reference,
## test Method
public String getMessage() {
   return "pura game hai";
}
## accessing it in Thymeleaf template 
<div th:text="${@utility.getMessage()}">...</div> 
This is fairly easy and might be useful in some scenarios. Happy Learning!! ☺

Wednesday, October 9, 2019

Web context objects: #httpServletRequest & #httpSession in Thymeleaf

Recently while working on a web application developed using Spring Boot & Thymeleaf, I came to know that Thymeleaf provides direct access to #httpServletRequest & #httpSession objects inside a web environment. These objects are also known as Web context objects. Today we would be discussing these objects and their usages with examples.
  • #httpServletRequest: It provides direct access to the javax.servlet.http.HttpServletRequest object associated with the current request.
    ## Usages
    ${#httpServletRequest.getParameter('foo')}
    ${#httpServletRequest.getAttribute('foo')}
    ${#httpServletRequest.getContextPath()}
    ${#httpServletRequest.getRequestName()}
    
    ## use case while using Script Inlining Feature of Thymeleaf
    <script th:inline="javascript" type="text/javascript">
    /*<![CDATA[*/
        ...
        var assignmentId = /*[[${#httpServletRequest.getParameter('assignmentid')}]]*/ 0;
    
    /*]]>*/
    </script>
    
    ## another example 
    <a th:if="${#httpServletRequest.getParameter('assignmentid') != null} and ${#httpServletRequest.requestURI eq '/studentassignment'}" 
       th:href="@{${#httpServletRequest.requestURI}(isbn=${bookModel.isbn},assignmentid=${#httpServletRequest.getParameter('assignmentid')})}"   
       th:text="${'Test Link'}">Test Link</a>
    
  • #httpSession: It provides direct access to the javax.servlet.http.HttpSession object associated with the current request.
    ## Usages
    ${#httpSession.getAttribute('foo')}
    ${#httpSession.id}
    ${#httpSession.lastAccessedTime}
Hoping that it might be useful for you guys. Happy Learning!! ☺

Different Expression Utility Objects in Thymeleaf With Examples

I bet every one of you must have performed one of the below tasks while development irrespective of the programming language you use for development:
  • Created a Utility class or 
  • Added utility methods in the existing Utility class or 
  • Used already written, existing Utility class methods for performing any common job 
You all would agree that knowing the available Utility classes in any language makes the developer's life easy. Therefore today we would be looking at various utility objects provided by Thymeleaf that help developers in performing common tasks in Thymeleaf expression like performing date formatting, performing numeric operations, performing String-related operation, etc. These utility objects are also known as Expression Utility Objects.

Expression Utility Objects


Below is the list of utility objects:
  • #dates: utility methods for java.util.Date objects: formatting, component extraction, etc.
    ## See javadoc API for class org.thymeleaf.expression.Dates
    <span th:if="${assignment.availableOn > #dates.createNow()}">
    <span th:text="${#dates.format(patient.currentDate, 'dd-MMM-yyyy')}">10-09-2019</span>
    
  • #calendars: analogous to #dates, but for java.util.Calendar objects.
  • #numbers: utility methods for formatting numeric objects.
    ## See javadoc API for class org.thymeleaf.expression.Numbers
    ## format decimal number by setting minimum integer digits and exact decimal digits
    <p th:with="num=${1.23345}" th:text="${#numbers.formatDecimal(num,2,3)}">01.233</p>
    <div th:text="${#numbers.formatDecimal(totalScore*0.1*100/totalMaxScore,0,0)}+'%'">
     80%</div>
    
  • #strings: utility methods for String objects: contains, startsWith, prepending/appending, etc.
    Example:
    ## See javadoc API for class org.thymeleaf.expression.Strings
    <span th:with="firstName=${#strings.substring(userModel.username,0,#strings.indexOf(userModel.username,' '))},
            lastName=${#strings.substring(userModel.username,#strings.indexOf(userModel.username,' ') + 1,#strings.length(userModel.username))},
            username=${ lastName + ', ' + firstName}" 
          th:data-username="${#strings.contains(userModel.username,' ') ? username : userModel.username}" 
          th:text="${username}"></span> 
    
  • #objects: utility methods for objects in general.
  • #bools: utility methods for boolean evaluation.
  • #arrays: utility methods for arrays.
  • #lists: utility methods for lists.
    ## See javadoc API for class org.thymeleaf.expression.Lists
    ## topicToFirstReadingTypeSubTopicMap is model attribute
    <select th:name="assetTopics" th:multiple="multiple">
     <option th:each="row : ${topicToFirstReadingTypeSubTopicMap}" 
             th:text="${row.key.label}" th:value="${row.value.nodeId}"  
             th:selected="${#lists.contains(objIdListForAsset, row.value.nodeId)}">Topic
     </option>
    </select> 
    ## assets is model attribute
    <div th:if="${not #lists.isEmpty(assets)}">...</div>
    
  • #sets: utility methods for sets.
  • #maps: utility methods for maps.
  • #aggregates: utility methods for creating aggregates on arrays or collections.
    ## See javadoc API for class org.thymeleaf.expression.Aggregates
    ## initially created a list of elements statically for demo and then used utilities
    <p th:with="array=${ {1,2,3} }" th:text="${#aggregates.sum(array)}">6</p>
    <p th:with="array=${ {1,2,3} }" th:text="${#aggregates.avg(array)}">2</p>
    
  • #messages: utility methods for obtaining externalized messages inside variables expressions, in the same way as they would be obtained using #{…} syntax.
  • #ids: utility methods for dealing with id attributes that might be repeated (for example, as a result of an iteration).
  • #execInfo: information about the template being processed.
  • #uris: methods for escaping parts of URLs/URIs.
  • #conversions: methods for executing the configured conversion service (if any).
Hoping that, these expression utility objects and given examples would help you while development. Happy Learning!! ☺

How to access model attributes inside JavaScript present in Thymeleaf templates?

The prime objective of this write up is to discuss "the how" of accessing model attributes inside JavaScript present in Thymeleaf templates. But I would also be touching on the situation in which I required to access the model attributes inside JavaScript present in Thymeleaf templates which would surely help one to design their web pages in a better manner.

1. Introduction


Thymeleaf offers a series of “scripting” modes for its inlining capabilities so that one can access their exposed Controller's model data inside scripts created in some script languages. Current available scripting modes are javascript (th:inline="javascript") and dart (th:inline="dart").
         I personally believe that it's good to know about the available features in any language like Thymeleaf but it's equally important to know exactly when to use which features? If you are only interested in knowing about Thymeleaf's Script Inlining feature then you could check out section 2 only but if you are also keen to know the instances where I have used this feature while developing a digital learning platform then you should also see section 3.

2. Script Inlining


Below is the sample code snippet which needs to be added in the Thymeleaf page for accessing our exposed Controller's model data inside JavaScripts:
<script th:inline="javascript" type="text/javascript">
/*<![CDATA[*/
    ...

    var username = /*[[${session.user.name}]]*/ 'Anshul';
    var isbn = /*[[${titleModel.isbn}]]*/ 0;
    var assignmentId = /*[[${#httpServletRequest.getParameter('assignmentid')}]]*/ 0;

    $(document).ready(function() {
      
 if ( assignmentId != 0 && assignmentId != null ) {
   ...
 } else {
   ...
 }
    });
/*]]>*/
</script>
where The /*[[...]]*/ syntax, instructs Thymeleaf to evaluate the contained expression.

Few pointers to note here:
  • Thymeleaf will execute the expression and insert the result, but it will also remove all the code in the line after the inline expression itself (the part that is executed when displayed statically). This expression evaluation is intelligent and not limited to Strings. Thymeleaf will correctly convert and write it in corresponding Javascript/Dart syntax. The following kinds of objects conversion are allowed: Strings, Numbers, Booleans, Arrays, Collections, Maps, Beans (objects with getter and setter methods).
  • Being a javascript comment (/*...*/), our expression will be ignored when displaying the page statically in a browser.
  • The code after the inline expression ('Anshul' or  0) will be executed when displaying the page statically.
  • One can also do it without comments with the same effects, but that will make the script to fail when loaded statically. 

3. Requirement & Design Discussion for a module


Recently I have participated in the design & development of a powerful digital learning platform using Microservice architecture. Today we would first know one of the module's requirements at very high level and then discuss different design approaches for developing that. It would give you an idea about when to use Thymeleaf's Script Inlining feature. 

Requirements:

  1. Provide the capability to teachers for managing their created assignments whereas allowing students to view their assigned assignments.
  2. The teacher could click on any assignment from the list of assignments and would see the assignment details page containing details like assignment status, assignment user details, etc in a tab beside the Manage Assignment tab. 
  3. There would be an option(button or Call To Action) in the assignment details tab to preview the questions present in the assignment. 

Design Discussion:


As usual, we too received the requirements gradually i.e. initially we got #1 then much later stage received #2 & #3. Since the layout of both the teacher's Manage Assignments page and student's My Assignments page was almost similar(both shows all the subtopic, multi-subtopic, topic, multi-topic assignments in list views for a title using accordion ) with only one subtle  difference that teacher would see all assignments with some additional details and extra privileges whereas students could see only their assignments. We discussed among us and agreed that we would create a single controller method and single Thymeleaf page for this requirement and would conditionally & dynamically form the page. We implemented this and it worked perfectly fine.

Now at a later stage, we received #2. Now we have to think about its design & implementation approach. Some facts are pretty clear like:
  •  One needs to make a service call to fetch the required assignment, add it in model attributes and dynamically form the Assignment Details tab. 
  • The current Manage Assignment/ My Assignments page data would now appear in a tab and besides that, we would have another tab called Assignment Details. One question pops up, is it a good idea to reload the whole page on click of the assignment and show both Manage Assignment and Assignment Details tab?  You are right Obviously not. So what we had in our hand then, two tabs on the page and same @RequestMapping path in the URL with one additional data i.e. query parameter "assignmentid". So the option for making direct service call was off the chart and it was evident that one needs to make an Ajax call from JavaScript to get assignment details and add the fetched data to the Assignment details tab.

Some more questions regarding the Thymeleaf's capability and implementation appeared like
  • Are Thymeleaf templates smart enough to detect the presence of assignment id in the URL and accordingly make Ajax call to fetch and add respective assignment data in the Assignment Details tab?
  • Do we have all the required parameters like ISBN of a title, "assignmentid" available in the JavaScript to make the service call?  
Now we needed to have the access to our exposed controller's model attributes inside JavaScript to make the service call. We came to know that one can use Thymeleaf's script inlining features to integrate our data inside scripts. 

One thing to note here that after receiving the #2 & #3, we have revisited our implementation for #1 and restructured it. What we did?

We have created a layout HTML page using Thymeleaf which contains
  • HTML article tag having Thymeleaf's th:replace attribute to add the fragments that would form the actual content of the page. This fragment contains multiple empty article tags having a unique id attribute to distinguish between the data for Manage Assignment/My assignments & Assignment Details tab. 
  • Using Thymeleaf's script inlining, we have made the controller's method required parameter available inside JavaScript and then conditionally made the corresponding service calls depending upon the presence of assignment id in the URL and populated the data using jQuery in the respective article tag.
  • One more interesting thing to note here, suppose a user directly wants to view particular assignment details only and not interested in viewing list of assignments then do you think is it a good idea to make two service calls, i.e. one for Manage Assignment/My assignments tab and one for Assignment Details tab? Obviously not right? Therefore we have applied the concept of lazy loading here using JavaScript and by adding a loaded flag. Initially loaded flag would be set to false which means Manage Assignment/My assignments tab is not loaded.  Manage Assignment/My assignments related controller's method would be called only if someone loaded it explicitly, closes the Assignment Details tab, switch to it from any other tabs. 
  • Later we received another requirement where we needed to show some other data in a separate tab on click of some Call to action buttons. Due to the above design approach, it has become very easy. We just added one more blank article tag in the fragment, made the Ajax call and added the data in the newly added article tag using jQuery. 

3. Conclusion


For developers, designers or architects, it's common to think about reusability, redundancy, modularity, readability, scalability while designing any software systems or a web-applications. Thymeleaf provides many features if used carefully could lead to better design of the maintainable, reliable software system. Today we have learned about the Script Inlining feature of Thymleaf and instances where it could be used. I hope it would surely help you while development. Happy Learning !!

Friday, September 20, 2019

How to prevent click on the specified HTML element using CSS, JS or jQuery

Recently I have got a simple requirement of making specified HTML element non-clickable conditionally. I am free to choose how to implement this i.e. either by using CSS, JS, jQuery. Today I would be sharing how I have achieved this. It might be not the best or optimal solution but it worked for me. Let me know what could be another possible solution for this.

Since the requirement was to make some HTML element non-clickable conditionally, I have used both jQuery and CSS to achieve the complete requirement. But I have used CSS property pointer-events: none to prevent the click on the specified HTML element. The pointer-events property defines whether or not an element reacts to pointer events. Here, I used two of its values i.e.
auto : The element reacts to pointer events, like hover and click. This is default
none : The element does not react to pointer events
$('#topicMenu').children('li:not(.selectedTopic)').css("pointer-events","auto"); //making it again clickable
$('#topicMenu').children('li:not(.selectedTopic)').css("pointer-events","none"); //making it non-clickable

Later I came through one more method using jQuery in StackOverflow but haven't verified it if it really works:
$('selector').click(false); //If using jQuery versions 1.4.3+:
$('selector').click(function(){return false;}); //else 
Feel free to share any new way to make the specified HTML element non-clickable. Happy Learning!!

Error while creating a project in STS - JSONException: A JSONObject text must begin with '{' at character 0

Recently while trying to create a Spring Boot project in my IDE i.e. Spring Tool Suite(STS, Version:3.9.2.RELEASE) using Spring Starter Project, I have got an error.

Replication Steps: In STS, navigated to File -> New -> Spring Starter Project, and as soon as I clicked on it, I got the error. The errors state that :

JSONException: A JSONObject text must begin with '{' at character 0


 Today I would be sharing the workaround and solution that worked for me. It might help someone who faces a similar issue while creating projects using their IDE.

Workaround & Solution:


Through STS, when anyone tries to create a Spring project then it internally uses Spring Initializr (https://start.spring.io) which is a quickstart generator for Spring projects. It simply means we have a workaround for this problem i.e. generating the project from our browser by accessing https://start.spring.io/, downloading a ZIP of the project, unpacking it locally and at last, importing it using "Import -> Maven -> Existing Maven Project" into STS.

The above workaround should surely work for everyone. It also suggests that our IDE i.e. STS is unable to connect with https://start.spring.io  and this is the root cause of this issue. But how to establish this connection, don't worry just follow the below steps:

Step 1: From STS navigate to Window -> Preferences -> General -> Network Connections
Step 2: In Network Connections, select 'Direct' from Active Provider dropdown and click on 'Apply and Close' button. Choosing Direct causes all the connections to be opened without the use of a proxy server.
Step 3: Now give it a try, create the project using STS i.e. File -> New -> Spring Starter Project.

It should work for you as well.
For reference,


Let me know in the comment section if the workaround and solution have worked for you or not. Happy Learning!!

Thursday, September 19, 2019

Spring Data Repositories: CrudRepository, PagingAndSortingRepository and JpaRepository

In the last article, we have learned about the benefits and significance of using Spring Data JPA. We have also seen how it has eliminated the need of writing boilerplate code in order to get the working JPA repository without much hassle. Today we would have a discussion on different types of Spring Data Repository interfaces, it's functionality and basic steps required for building a repository.

1. Introduction


The goal of Spring Data repository abstraction is to significantly reduce the amount of boilerplate code required to implement data access layers for various persistence stores. Spring Data JPA provides various types of repository interfaces which could be extended depending upon the requirements to create our custom repository interface(not the implementation). Let's start our discussion.

2. Spring Data Repositories


We would be using below Repository interfaces to create our custom Repository interface:
  • CrudRepository extends Repository interface and should be used for generic CRUD operations on a repository.
  • PagingAndSortingRepository extends CRUDRepository interface and should be used when one needs to retrieve entities using the pagination and sorting abstraction.
  • JpaRepository extends PagingAndSortingRepository & QueryByExampleExecutor interface and should be used when one has the requirement to delete entities in a batch or flushing the persistence context which could be either flushing all pending changes to the database or saving an entity and flushing the changes instantly.
That means, the central interface in Spring Data repository abstraction is Repository & JpaRepository contains the full API of CrudRepository and PagingAndSortingRepository. But one should choose the repository interface based on their intended requirement. 

3. Steps for building a repository 


Below are the steps for building a repository interface with an example:
Step 1: Map the required POJO.
Step 2: Declare our domain class-specific custom interface extending Repository interface or one of its subinterfaces and type it to the domain class that it would handle.
public interface UserRepository extends CrudRepository<User, Long> { … }
Step 3: Declare query methods on the interface.
List<User> findByLastname(String lastname);  //Inferred Query
One could write inferred, JPQL or Native queries as per their requirements. Above is the example of the inferred query where one doesn't need to tell Spring Data what to do since it automatically infers the SQL query from the name of the method name.
Step 4: Configure Spring to scan for repository interfaces and create implementations.
Step 5: Get the repository instance injected in our Service class and then use it.
public class YourService {

  @Autowired
  private UserRepository repository;

  public void doSomething() {
    List<User> users = repository.findByLastname("Agrawal");
  }
}

4. Conclusion


I am sure you all would save a lot your effort and time in implementing your data access layers if you are using Spring Data Repositories. Just remember when to use which Spring Data Repository interface and you are good to go. Happy Learning!!

Wednesday, September 18, 2019

Introduction to Spring Data JPA

In the last project, I have used two main modules of Spring Data family i.e. Spring Data JPA which provides Spring Data repository support for JPA & Spring Data REST for exporting Spring Data repositories as hypermedia-driven RESTful resources. Today, we would be discussing Spring Data JPA, it's benefits, and why one should use it?

1. Introduction


With JPA, we are already implementing the data access layer of our application but the real question was, do we think our efforts and time are justified in writing too much boilerplate code to execute simple queries as well as perform pagination, and auditing. Spring Data JPA aims to significantly improve the implementation of data access layers.

2. What is Spring Data JPA


Let us first understand what Spring Data JPA is not?
  • Unlike the JPA, which is a specification that defines the API for ORM and for managing persistent objects, Spring Data JPA is not a specification. 
  • Spring Data JPA is not a JPA provider like Hibernate. 
Spring Data JPA is a library/framework that adds an extra layer of abstraction on the top of JPA that makes a developer's life easy by providing a way to easily implement JPA based repositories. As a developer, one has to write the repository interfaces, including custom finder methods, and Spring would automatically provide the implementation.

3.  Why Spring Data JPA


Anyone who has worked in implementing data access layer (DAO) of a traditional enterprise application using JPA & Hibernate would surely understand how much code must be written in order to interact with the database for CRUD operations. Not only that, one might have to write a similar CRUD operation code for other entities. It simply signifies that implementing a data access layer of an application is cumbersome and also leads to a lot of boilerplate code. We would see the glimpse of  DAO(Data Access Object) implementation using both the approaches i.e. JPA+ Hibernate VS Spring Data JPA + Hibernate. One could decide for themselves, which one is better? 

JPA + Hibernate DAO Implementation


package anshulsblog.spring.web.daoImpl;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;


@Repository
public class SampleDaoImpl implements SampleDao {

    @PersistenceContext(unitName = "jpa_unit")
    private EntityManager entityManager;
    private final Logger logger = Logger.getLogger(SampleDaoImpl.class);

    public EntityManager getEntityManager() {
        return entityManager;
    }

    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }
 
    @Override
    @Transactional
    public boolean editUserName(Long userId, String userName) {
        logger.info("SampleDaoImpl : editUserName");
        boolean isEdited = true;
        try {
            StringBuilder sb = new StringBuilder(" UPDATE user u ");
            sb.append(" SET u.userName = ? ");
            sb.append(" WHERE  u.userid = ? ");
            String sql = sb.toString();
            Query nativeQuery = getEntityManager().createNativeQuery(sql);
            nativeQuery.setParameter(1, userName);
            nativeQuery.setParameter(2, userId);
            nativeQuery.executeUpdate();
            getEntityManager().flush();
        } catch (Exception ex) {
            logger.error(ex.getMessage());
            isEdited = false;
        }
        return isEdited;
    }

    @Override
    public String getUserName(Long userId) {
        logger.info("SampleDaoImpl : getUserName");
        String userName = "";
        try {
            StringBuilder sb = new StringBuilder(" SELECT u.username FROM user u ");
            sb.append(" WHERE u.id = ? ");
            String sql = sb.toString();
            Query nativeQuery = getEntityManager().createNativeQuery(sql);
            nativeQuery.setParameter(1, userId);
            List resultList = nativeQuery.getResultList();

            if (!resultList.isEmpty()) {
                for (int i = 0; i < resultList.size(); i++) {
                    userName = resultList.get(i).toString();
                }
            }
        } catch (Exception ex) {
            logger.error(ex.getMessage());
        }
        return userName;
    }
}

Spring Data JPA + Hibernate

Here we have created the Repository Interface and Spring would automatically provide the implementation. To know more about various Spring Data Repository interfaces, their functionality and how to build a repository, check out this article.

package com.anshulsblog.repository;
 
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.transaction.annotation.Transactional;

import com.anshulsblog.model.User;
 
public interface UserRepository extends CrudRepository<User, Long> {

@Transactional( readOnly = true )
User findByUserId(Long uesrId);

@Modifying
@Transactional
@Query(value ="UPDATE User u set u.userName = :username where u.userid = :userId")
boolean editUserName(@Param("userid") Long userId, @Param("username") String userName)
}

Have you noticed anything in the above implementation?

You got it right. The first method doesn't have any query attached to it. But it would give us the desired results. Thinking how? Here, Spring Data JPA is generating database queries based on the method names.

Just saying, in the second method also, we have used JPQL that means even if we change our underlying database it would work without any change.

4. Spring Data JPA Features


  • Sophisticated support to build repositories based on Spring and JPA 
  • Validation of @Query annotated queries at the bootstrap time - For testing purpose, try writing some wrong query then one would notice detailed logs explaining the errors in query and application would not start. 
  • Pagination support, dynamic query execution, ability to integrate custom data access code
  • Transparent auditing of the domain class

5. Conclusion 


Hoping that we all have understood the main reason or motivation behind the arrival of Spring Data JPA. The pain that it takes away, the repetitive tasks that developers don't have to do again and again while implementing the data access layers. Happy Learning!!

Thursday, September 12, 2019

JPA VS Hibernate Debate: Which came first?

Recently we had a very healthy debate at work on the topic JPA VS Hibernate similar to the chicken or the egg causality dilemma which is commonly stated as "which came first: the chicken or the egg?".

Few people are in favor of JPA came first whereas few are in favor of Hibernate. Both the team have their own arguments to substantiate their claim. Let's hear out those arguments first because you might find it interesting as well as logical. After that, we would jump on the final verdict.

If you have a basic idea about JPA and Hibernate then skip point (1) and directly jump to point (2).

1. What are JPA and Hibernate?


  • JPA is a specification whereas Hibernate is Red Hat’s implementation of the JPA specification.
  • There is only one JPA specification. But, there are many different implementations like Hibernate, TopLink, EclipseLink, OpenJPA, DataNucleus. 
  • The JPA specification is collaboratively developed through the Java community process (JCP) and updates are released as Java specification requests (JSRs). If the community agrees upon all of the changes proposed within a JSR, a new version of the API is released. For example, Development of a maintenance release as JPA 2.2 was done under JSR 338. The maintenance review was approved on 19 June 2017. Just look at the participant's list below who involved in the evolution of the API:

2. The Arguments


Assumption:  [Team A JPA came first, Team B - Hibernate came first]


Team A: JPA came first. Just tell me, have we developed any piece of software till now where we haven't discussed it's design, architecture before starting the actual development or implementation? Don't we keep guidelines, best practices, industry & organization-specific conventions, design patterns, constraints in the back of our head before actually jumping on the implementation?

JPA is a specification which means it provides a set of documented requirements, designs (APIs, kind of Interface) that must be satisfied when anyone builds an implementation for persisting, reading, and managing data from our Java object to relational tables in the database. Using this specification only i.e. Java Persistence API(JPA), one could develop any implementation.

Based on the design, we implement the piece of software right? Also, we all know that design comes before development in SDLC. JPA is a design, and Hibernate is the implementation based on that design.

Now you decide yourself, which came first. 

Team B: Hibernate and other ORM tools were already present there before JPA came in the picture. If you really understand the reason Why JPA was invented in the first place?  then you would automatically agree with our point. Tell me what do you think about the benefits that JPA brings on the table? 
You said it right and articulated it in a nice manner
1) It's a common standard that any ORM solution provider adheres to.
2) vendor/implementation-neutrality and compatibility -If one uses the standard JPA while development, then one is keeping their options open to switch to other JPA implementations.

Because of these benefits, we are saying Hibernate came first. It's another way around.

Initially, there were many ORM tools having more or less similar APIs and serving the exact same purpose. But, it's very tedious and difficult to switch between these ORM implementations as they are not following any common standards. To address this difficulty, JPA came in the picture whose goal was to standardize how Java applications performed ORM.

The Verdict


We had a very healthy discussion among Team A & Team B around this topic and their arguments seem quite logical and promising. But we haven't reached to any conclusion yet so we switched to Google in search of our pursuit and found that the verdict was in favor of Team B.

The final release date of the JPA 1.0 specification was 11 May 2006 as part of Java Community Process JSR 220 whereas Hibernate initial release was 23 May 2001. [Reference from Wikipedia].

On further research, we came to know that prior to the initial release of JPA 1.0 in 2006, there were a number of vendors competing in the object-relational mapping (ORM) tools space, all of them have more or less very similar APIs and obviously serving the exact same purpose. But, it's very difficult to switch between these ORM implementations. The goal of JPA was to standardize how Java applications performed ORM.

Our research cleared some more doubts, misunderstanding and misconception about JPA and Hibernate. If you are interested in those then bear with us some more time.

Misunderstanding


Two most common misunderstandings:
  • Comparing JPA and Hibernate: Ask yourself, can we compare two different entities? If your answer is No then why are we comparing JPA and Hibernate in the first place?  Because JPA is the specification whereas Hibernate is an implementation. Mind it, because of Hibernate’s popularity, many people still continuing to use the term Hibernate when they really meant JPA. 
  • One has to choose between JPA or Hibernate: Gone are days(early JPA release) when the choice between JPA and Hibernate was a legitimate decision for any technical architect to take. Now all of the functionality provided by Hibernate can simply be accessed through the JPA API(latest release JPA 2.2 closed the gap between two). But be aware and informed, it might happen even today that, there are advanced features baked into the Hibernate framework that aren’t yet available through the JPA specification because of two reasons:
    • JPA is guided by the JCP and JSR process, it’s often a slow and time taking process to add new features.
    • Hibernate project isn’t bound by these sorts of restrictions, they can make features available much faster through their proprietary APIs.
What if one needs the more advanced feature present in Hibernate and that could not be accessed through the JPA API then one need to choose from two right?
We would say why don't we leverage the advantage of both JPA and Hibernate but the questions is how? - One could always write code that bypasses JPA and calls the Hibernate code directly. We might be already doing this in actual practice. For example: Developers could call upon proprietary Hibernate APIs, such as the HibernateSession within their code, while at the same time, they would decorate their JavaBeans and POJOs with JPA-based annotations to simplify the mapping between the Java code and the relational database in use. 

No one needs to choose between Hibernate and JPA. One either chooses to use JPA or not. And if one does choose to use the JPA to interact with their relational database systems, they would choose between the various implementations.

Happy Learning! Hoping that if you are having the same misunderstanding as ours then this write up would surely help you to clear your dilemma. 

Wednesday, September 4, 2019

Solve: QTJava.zip was unexpected at this time error occurred while starting ZooKeeper

Recently I have got an error i.e. \QuickTime\QTSystem\QTJava.zip was unexpected at this time. while starting ZooKeeper that comes packaged with Kafka on Windows system. One might face a similar issue while quickly setting up the Kafka Cluster on Windows systems. That's why sharing the solution.

Error:

D:\kafka\kafka_2.12-2.3.0>bin\windows\zookeeper-server-start.bat config\zookeeper.properties
\QuickTime\QTSystem\QTJava.zip was unexpected at this time.

D:\kafka\kafka_2.12-2.3.0>

Solution:

The error was happening due to the spaces in the folder name present in the %CLASSPATH% environment variable. One just needs to remove the spaces and it would work. 

When I used echo %CLASSPATH% command in CMD it showed me below value:
.;C:\Program Files (x86)\QuickTime\QTSystem\QTJava.zip

I just removed the above entry from CLASSPATH environment variable and tried starting the Zookeeper, it worked like charm. 

Somehow the batch script i.e. zookeeper-server-start.bat is unable to handle the spaces in the environment variables. For me, it has happened due to the CLASSPATH environment variable, but someone might get an error if they have space containing entries in their PATH or JAVA_HOME environment variable. 

Happy Learning!! Let me know if you face this issue and if this solution worked for you also in the comments section.