Subscribe To Our Newsletter
You will receive our latest post and tutorial.
Thank you for subscribing!

required
required


Javascript Fundamentals Part 1

Javascript is case-sensitive

Everything in JavaScript including variables , function names,  class names, and operators are case-sensitive. It means that counter and Counter variables are different.

Comments

JavaScript supports both single-line (//) and block(/**/) comments.

// This is a single line comment

/*
* This is a multiple line 
* comment block
*/

Semicolon

Although JavaScript does not require to end a statement with a semicolon (;), it is recommended to always use the semicolon to end a statement which makes your code more readable.

var number1 = 1;
var number2 = 2;

Javascript variables

JavaScript variables are loosely typed which means that variables can hold values with any type of data. Variables are just placeholders for values.

To declare a variable, you use the var or let keyword followed by the variable name.

var pointer = "Welcome!";
point = 100;

Undefined and undeclared variables

An undefined variable is a variable that has been declared. Because we have not assigned it a value, the variable used the undefined as its initial value.

var undefinedMessage;

console.log(undefinedMessage); // undefined

An undeclared variable is the variable that has not been declared.

console.log(undeclaredVariable); // ReferenceError: undeclaredVariable is not defined

Global and local variables

In JavaScript, all variables exist within a scope that determines the lifetime of the variables and which part of the code can access them.

Local variables

Variables declared within a JavaScript function, become locally accessible to the function and only that function.

function sayHi(){
    //helloMsg is a local variable to the sayHi() function
    var helloMsg = "Welcome!";
    console.log("helloMsg: "+helloMsg);
}

sayHi();

console.log("helloMsg: "+helloMsg);//Uncaught ReferenceError: helloMsg is not defined

Global variables

A variable declared outside a function, becomes global which all functions on a web page can access it. 

/*
* Global variables
*/
var message = "Hello";
function sayHello() {
    // local variable
    message = 'Hi';
    console.log(message); // which message?
}
sayHello();// Hi
console.log(message); // Hi

If a local variable is not declared, Javascript will create it as a global variable.

But to avoid creating a global variable accidentally inside a function because of omitting the var keyword, you use the strict mode by adding the “use strict”; at the beginning of the JavaScript file (or the function). Note that by using “use strict” modern javascript will be enforced.

<script>
"use strict";
window.onload = function() {

}
</script>

Javascript Data Types

JavaScript has six primitive data types:

  1.  null
  2.  undefined
  3.  boolean
  4.  number
  5.  string
  6.  symbol – available only from ES6
  7. object

JavaScript has dynamic types. This means that the same variable can be used to hold different data types.

var x;           // Now x is undefined
x = 10;           // Now x is a Number
x = "Folau";      // Now x is a String

To get the current type of the value of a variable, you use the typeof operator.

let count = 120; // count is a number
console.log(typeof(count)); // "number"

count = false;   // count is now a boolean
console.log(typeof(count)); // "boolean"

count = "Hi";   // count is now a string
console.log(typeof(count)); // "string"

The null type

Javascript defines that null is an empty object pointer. It is a good practice to assign a variable that later holds an object to null so that you can check whether the object is null or not by using the if statement.

let obj = null;
console.log(typeof obj); // object

if(obj != null) {
   // call method of the object
}

The undefined type

The undefined type is a primitive type that has one value undefined. By default, when a variable is declared but not initialized, it is assigned the value undefined.

The number type

Variables that hold whole number values

var num = 100;
var dec = 2.5;

The boolean type

Variables that hold true or false

var isSafe = true;

The NAN type

JavaScript has a special numeric value called NAN, which stands for Not a Number. In fact, it means an invalid number.

console.log('john'/2);//NaN;
console.log(NAN/2);//NAN
console.log(NAN==NAN);//false

The string type

In JavaScript, a string is a sequence of zero or more characters. A literal string begins and ends with either a single quote(‘) or double quote (“). A string that starts with a double quote must end with a double quote and a string that begins with a single quote must end with a single quote.

let greeting = 'Hi';
let s = "It's a valid string";
let str = 'I\'m also a string'; // use \ to escape the single quote (')

The object type

In JavaScript, an object is a collection of properties, where each property is defined as a key-value pair.

let user = {
    firstName: 'Folau',
    lastName: 'Kaveinga'
};

 

Null check with ??

The nullish coalescing operator is written as two question marks ??.

The result of a ?? b is:

  • if a is defined, then a,
  • if a isn’t defined, then b.
let collegeName;

console.log("collegeName: "+ (collegeName ?? "no collegeName"));//collegeName: no collegeName

collegeName = "BYU";
console.log("collegeName: ", collegeName ?? "no collegeName");// BYU

 

Source code on Github

October 10, 2020

Springboot Retry

Spring framework has a retry project that is very useful when you have a business logic failure that you want to be able to retry to complete.

 

<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

 

@Configuration
@EnableRetry
public class GlobalConfig {

}

 

 

@Service
@Slf4j
public class UserServiceImp implements UserService {

    @Retryable(value = {RuntimeException.class}, maxAttempts = 3, backoff = @Backoff(delay = 2000))
    @Override
    public boolean sendEmail(User user) throws RuntimeException {
        log.info("send email");
        if (true) {
            throw new RuntimeException("error");
        }

        return false;
    }

    @Recover
    @Override
    public boolean recover(RuntimeException e, User user) {
        log.info("recover");
        return true;
    }

}

 

October 7, 2020

Java Date

The class Date epresents a specific instant in time, with millisecond precision.

After Method

Returns true if the invoking Date object contains a date that is later than the one specified by date, otherwise, it returns false.

Date today = DateUtils.addDays(new Date(), 0);
Date yesterday = DateUtils.addDays(new Date(), -1);

System.out.println("today - " + today.toInstant().toString());
System.out.println("yesterday - " + yesterday.toInstant().toString());
System.out.println("today.after(yesterday) - " + today.after(yesterday));
System.out.println("today.equals(yesterday) - " + today.equals(yesterday));
System.out.println("yesterday.after(today) - " + yesterday.after(today));

// Output
today - 2020-10-02T04:34:35.465Z
yesterday - 2020-10-01T04:34:35.480Z
today.after(yesterday) - true
today.equals(yesterday) - false
yesterday.after(today) - false

 

Before Method

Returns true if the invoking Date object contains a date that is earlier than the one specified by date, otherwise, it returns false.

Date today = DateUtils.addDays(new Date(), 0);
Date yesterday = DateUtils.addDays(new Date(), -1);

System.out.println("today - " + today.toInstant().toString());
System.out.println("yesterday - " + yesterday.toInstant().toString());

System.out.println("today.before(yesterday) - " + today.before(yesterday));
System.out.println("today.equals(yesterday) - " + today.equals(yesterday));
System.out.println("yesterday.before(today) - " + yesterday.before(today));

// output
today - 2020-10-02T15:48:24.823Z
yesterday - 2020-10-01T15:48:24.837Z
today.before(yesterday) - false
today.equals(yesterday) - false
yesterday.before(today) - true

 

Check if same two dates are the same day

/**
 * Check if day1 is the same day as day2<br/>
 * day1 - 2020-6-12, day2 - 2020-6-13, return false <br/>
 * day1 - 2020-6-12, day2 - 2020-6-12, return false <br/>
 * day1 - 2020-6-13, day2 - 2020-6-12, return false <br/>
 */
public static boolean isSameDay(Date day1, Date day2) {
    if (day1 == null || day2 == null) {
        return false;
    }
    final Calendar cal1 = Calendar.getInstance();
    cal1.setTime(day1);
    final Calendar cal2 = Calendar.getInstance();
    cal2.setTime(day2);

    return cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) && cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) && cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH)
            && cal1.get(Calendar.DAY_OF_MONTH) == cal2.get(Calendar.DAY_OF_MONTH);
}

 

Check if day1 is after day2

/**
 * Check if day1 is after day2<br/>
 * day1 - 2020-6-12, day2 - 2020-6-13, return false <br/>
 * day1 - 2020-6-12, day2 - 2020-6-12, return false <br/>
 * day1 - 2020-6-13, day2 - 2020-6-12, return true <br/>
 */
public static boolean isAfterDay(Date day1, Date day2) {
    if (day1 == null || day2 == null) {
        return false;
    }
    final Calendar cal1 = Calendar.getInstance();
    cal1.setTime(day1);
    final Calendar cal2 = Calendar.getInstance();
    cal2.setTime(day2);

    if (cal1.get(Calendar.YEAR) < cal2.get(Calendar.YEAR)) {
        return false;
    } else if (cal1.get(Calendar.MONTH) < cal2.get(Calendar.MONTH)) {
        return false;
    } else if (cal1.get(Calendar.DAY_OF_MONTH) <= cal2.get(Calendar.DAY_OF_MONTH)) {
        return false;
    }

    return true;
}

Check if day1 is before day2

/**
 * Check if day1 is before day2<br/>
 * day1 - 2020-6-12, day2 - 2020-6-13, return true <br/>
 * day1 - 2020-6-12, day2 - 2020-6-12, return false <br/>
 * day1 - 2020-6-13, day2 - 2020-6-12, return false <br/>
 */
public static boolean isBeforeDay(Date day1, Date day2) {
    if (day1 == null || day2 == null) {
        return false;
    }
    final Calendar cal1 = Calendar.getInstance();
    cal1.setTime(day1);
    final Calendar cal2 = Calendar.getInstance();
    cal2.setTime(day2);

    if (cal1.get(Calendar.YEAR) > cal2.get(Calendar.YEAR)) {
        return false;
    } else if (cal1.get(Calendar.MONTH) > cal2.get(Calendar.MONTH)) {
        return false;
    } else if (cal1.get(Calendar.DAY_OF_MONTH) >= cal2.get(Calendar.DAY_OF_MONTH)) {
        return false;
    }

    return true;
}

 

October 2, 2020

Elasticsearch Installation

Local Installation

Installing Elasticsearch on your local Mac computer. I have a Mac laptop so this local installation will be for Mac users but you can google Elasticsearch Windows installation.

I use docker and here is the docker command, 

docker pull docker.elastic.co/elasticsearch/elasticsearch:7.1.0

Once you have pulled the elasticsearch image, run the following command to start Elasticsearch 

docker run -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:7.1.0

If you want to keep your local Elasticsearch server running at all times then run this command. Even when you turn off your computer, it will start back up when you computer comes back on.

docker run -p 9200:9200 -p 9300:9300 --name elasticsearch -e "discovery.type=single-node" -dit --restart unless-stopped -d docker.elastic.co/elasticsearch/elasticsearch:7.1.0

To check if installation well, go to localhost:9200/_cat/nodes?v&pretty on your browser.

You should see something like this which is the status of your Elasticsearch node.

ip         heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
172.17.0.3           20          96   0    0.00    0.02     0.00 mdi       *      f3056ceb45a2

You also need to install kibana which is a UI interface that works with Elasticsearch

Docker command to pull kibana docker image

docker pull docker.elastic.co/kibana/kibana:7.1.0

Run this command to start your kibana server

docker run --link YOUR_ELASTICSEARCH_CONTAINER_NAME_OR_ID:elasticsearch -p 5601:5601 {docker-repo}:{version}

 

 

 

September 24, 2020

Elasticsearch Search API

You can search data in Elasticsearch by sending a get request with query string as a parameter or post a query in the message body of post request. A search query, or query, is a request for information about data in Elasticsearch data streams or indices. 

GET doctor_ut/_search
{
  "query": {
    "match_all": {}
  }
}

 

Java example of search API

String indexName = Index.DOCTOR_UT.name().toLowerCase();

SearchRequest searchRequest = new SearchRequest(indexName);
searchRequest.allowPartialSearchResults(true);
searchRequest.indicesOptions(IndicesOptions.lenientExpandOpen());

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.termQuery("addresses.state.keyword", "UT"));

int from = 1;
int size = 1000;

searchSourceBuilder.from(from);
searchSourceBuilder.size(size);
searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));

searchRequest.source(searchSourceBuilder);

// with sorting
// log.info("{\"query\":{}, \"sort\":{}}", searchSourceBuilder.query().toString(),
// searchSourceBuilder.sorts().toString());

log.info("\n{\n\"query\":{}\n}", searchSourceBuilder.query().toString());

SearchResponse searchResponse = null;

try {
   searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

} catch (Exception e) {
    log.warn(e.getLocalizedMessage());
}

log.info("search got response from elastic!, totalHits={}, maxScore={}, hitLength={}", searchResponse.getHits().getTotalHits().value, searchResponse.getHits().getMaxScore(),searchResponse.getHits().getHits().length);

Iterator<SearchHit> it = searchResponse.getHits().iterator();

while (it.hasNext()) {
    SearchHit searchHit = it.next();

    try {
       // log.info(searchHit.getSourceAsString());
       DoctorIndex doctorIndex = ObjectUtils.getObjectMapper().readValue(searchHit.getSourceAsString(), DoctorIndex.class);
       log.info("doctorIndex={}", ObjectUtils.toJson(doctorIndex));

       // ObjectUtils.getObjectMapper().writeValue(new FileOutputStream("output-2.json", true),
       // doctorIndex);

    } catch (Exception e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
    }
}

Search API Pagination

By default, the  Search API  returns the top 10 matching documents. 

To paginate through a larger set of results, you can use the search API’s size and from parameters. The size parameter is the number of matching documents to return. The from parameter is a zero-indexed offset from the beginning of the complete result set that indicates the document you want to start with.

By default, you cannot page through more than 10,000 documents using the from and size parameters. This limit is set using the index.max_result_window index setting.

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); 
searchSourceBuilder.query(QueryBuilders.termQuery("addresses.state.keyword", "UT")); 
int from = 1; 
int size = 1000; 
searchSourceBuilder.from(from); 
searchSourceBuilder.size(size);
GET doctor_ut/_search
{
  "from": 5, 
  "size": 5,
  "query": {
    "match_all": {}
  }
}

 

Search Scroll API

The Scroll API can be used to retrieve a large number of results from a search request.

While a search request returns a single “page” of results, the scroll API can be used to retrieve large numbers of results (or even all results) from a single search request, in much the same way as you would use a cursor on a traditional database.

Scrolling is not intended for real time user requests, but rather for processing large amounts of data, e.g. in order to reindex the contents of one data stream or index into a new data stream or index with a different configuration.

The scroll API requires a scroll ID. To get a scroll ID, submit a  search API  request that includes an argument for the scroll query parameter . The scroll parameter indicates how long Elasticsearch should retain the  search context  for the request.

The search response returns a scroll ID in the _scroll_id response body parameter. You can then use the scroll ID with the scroll API to retrieve the next batch of results for the request.

You can also use the scroll API to specify a new scroll parameter that extends or shortens the retention period for the search context.

The scroll API returns the same response body as the search API

GET doctor_ut/_search/scroll
{
  "scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ=="
}
final Scroll scroll = new Scroll(TimeValue.timeValueMinutes(1L));
SearchRequest searchRequest = new SearchRequest(indexName);
searchRequest.allowPartialSearchResults(true);
searchRequest.indicesOptions(IndicesOptions.lenientExpandOpen());
searchRequest.scroll(scroll);

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.size(1000);
searchSourceBuilder.query(QueryBuilders.termQuery("addresses.state.keyword", "UT"));
searchRequest.source(searchSourceBuilder);

SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
log.info("search got response from elastic!, totalHits={}, maxScore={}, hitLength={}", searchResponse.getHits().getTotalHits().value, searchResponse.getHits().getMaxScore(),
                    searchResponse.getHits().getHits().length);

// process searchResponse

String scrollId = searchResponse.getScrollId();
SearchHit[] searchHits = searchResponse.getHits().getHits();

while (searchHits != null && searchHits.length > 0) {

   SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);
   scrollRequest.scroll(scroll);
   searchResponse = restHighLevelClient.scroll(scrollRequest, RequestOptions.DEFAULT);

   log.info("search got response from elastic!, totalHits={}, maxScore={}, hitLength={}", searchResponse.getHits().getTotalHits().value, searchResponse.getHits().getMaxScore(),
                        searchResponse.getHits().getHits().length);

   // process searchResponse

   scrollId = searchResponse.getScrollId();
   searchHits = searchResponse.getHits().getHits();
}

ClearScrollRequest clearScrollRequest = new ClearScrollRequest();
clearScrollRequest.addScrollId(scrollId);
ClearScrollResponse clearScrollResponse = restHighLevelClient.clearScroll(clearScrollRequest, RequestOptions.DEFAULT);
boolean succeeded = clearScrollResponse.isSucceeded();

 

 

September 24, 2020