aha-moments

Notes

Array
ArrayList
Linked List
HashSet
TreeSet
HashMap
TreeMap
Queue
Stack
SQL
JavaScript
React.js
ASP.NET
Ember.js
Spring Boot
Collection Framework

Backend to Frontend
Frontend to Backend

1 million = 1,000,000 i.e. 1_000_000

Array

## ArrayList import java.util.ArrayList;

We cannot specify int as the type of an ArrayList. An int is not a “ReferenceType.” We have to use Integer as the type because ArrayLists can only hold objects, not primitive values. Infact we cannot use any primitive type in ArrayList. Primitive types are the most basic data types available within the Java language. There are 8: boolean , byte , char , short , int , long , float and double

  // Creating an empty ArrayList of string type
  ArrayList<String> al = new ArrayList<String>();

  // Populating the ArrayList by custom elements
  al.add("Mike Tyson");
  al.add("Chuck Norris");
  al.add("Roronoa Zoro");
  al.add("Yagami Light");

  // Converting above List to array using toArray()
  // method and storing it in an string array
  String k[] = al.toArray(new String[al.size()]);
  List<Integer> list = new ArrayList<>();
  int[] arr = list.toArray(new int[list.size()]);

We need to pass in the size of ArrayList to the array.

  Int[] arr = new int[5];
  List<Integer> list = Arrays.asList(arr);

LinkedList

HashSet


## TreeSet
- Create a reverse order view of the elements contained in a given Tree Set
    TreeSet<String> set = new TreeSet<>();
    set.add("red");
    set.add("orange");
    set.add("yellow");
    set.add("green");
    NavigableSet<String> reverseSet = set.descendingSet();
    System.out.println("Reverse set: " + reverseSet);
    
- Find the numbers less than 7 in a Tree Set
```sh
    TreeSet<Integer> set = new TreeSet<>();
    set.add(1);
    set.add(3);
    set.add(5);
    set.add(7);
    set.add(9);


    TreeSet<Integer>lessThanSeven = (TreeSet<Integer>) set.headSet(7);
    System.out.println("Numbers less than 7: " + lessThanSeven);

HashMap

TreeMap

	
- Get a key-value mapping associated with the greatest key and the least key in a map
```sh
          TreeMap<String, Integer> map = new TreeMap<>();
    map.put("A", 1);
    map.put("B", 2);
    map.put("C", 3);
    map.put("D", 4);

    System.out.println("Original TreeMap: " + map);
    System.out.println("Mapping for greatest key: " + map.lastEntry());
    System.out.println("Mapping for least key: " + map.firstEntry());
    
    // Original TreeMap: {A=1, B=2, C=3, D=4}
    // Mapping for greatest key: D=4
    // Mapping for least key: A=1

Queue

Stack

-

Structured query language (SQL)

ALTER TABLE table_name ADD column_name VARCHAR (255) NOT NULL DEFAULT 'default_name' AFTER some_column_name; 

That is, to add a settings to a stores table we can add a column called has_analytics with default value of 0, which represents False

ALTER TABLE stores ADD has_analytics tinyint NOT NULL DEFAULT 0;

JavaScript

arr.forEach(item => { setTimeout(() => console.log(item), item); })

 
## React.js
  	- Using react.js with TypeScript and JavaScript
  	- Using Material UI's component, [MUI](https://mui.com/)
  	- Using [constate](https://github.com/diegohaz/constate) for the state management
  	- In React we need to use useMemo to stop rerendering every time. 
  	- Even if we change a value in the react, it would rerender all the components.
  	- When we change a value, React rerenders all the components eventhough those components are not using that value.
  	- So, it is little bit difficult to stop rerendering each time. 
  
## ASP.NET
	-

## Ember.js
  	- In Ember the page doesn't rerender like it does in React.
  
## Spring Boot
	-

## Collection Framework 
```sh
  ArrayList has a faster access time for retrieving elements but slower insertion and deletion time, while LinkedList has faster insertion and deletion     time but slower access time.

Backend to Frontend

In Spring Boot, you can create RESTful APIs that can return data in various formats, such as JSON or XML.
JSON is the most common format used for exchanging data between a Spring Boot backend and a React.js frontend.<br<

To pass data from a Spring Boot backend to a React.js frontend in JSON format, you can create a REST endpoint in Spring Boot that returns the data as a JSON object. Here’s an example of a Spring Boot controller method that returns a list of books in JSON format: ```sh @RestController @RequestMapping(“/books”) public class BookController {

@Autowired
private BookService bookService;

@GetMapping
public List<Book> getAllBooks() {
    return bookService.getAllBooks();
} } ``` > In this example, the @RestController annotation is used to define a REST endpoint for handling HTTP GET requests to the /books URL path. The getAllBooks() method returns a list of Book objects, which is automatically serialized into JSON format by Spring Boot.

On the React.js side, you can use the fetch() API or a third-party library like Axios or jQuery to make an HTTP GET request to the Spring Boot endpoint and retrieve the JSON data. Here’s an example of how to use the fetch() API to get the list of books from the Spring Boot endpoint:

fetch('/books')
  .then(response => response.json())
  .then(data => {
    // do something with the data
  });

In this example, the fetch() function sends an HTTP GET request to the /books URL path and receives a JSON response. The response.json() method is called to parse the JSON response into a JavaScript object, which can then be used in the data variable.

Serialization

Serialization is the process of converting an object into a format that can be easily transmitted over a network or stored in a file or database. In the case of sending data from a Spring Boot backend to a React.js frontend, serialization is necessary to convert the data into a format that can be transmitted as a response to an HTTP request.

Serialization is necessary because the data being transmitted needs to be in a format that can be easily understood and interpreted by both the backend and frontend applications. In the case of Spring Boot and React.js, the data is typically serialized into a JSON format, which is a lightweight and widely-used format for transmitting data over the web.

By serializing the data into a standardized format like JSON, it becomes possible for the backend and frontend applications to communicate with each other in a way that is platform and language independent. This means that the same data can be transmitted and interpreted by a wide variety of different systems and programming languages, which makes it much easier to build interoperable applications.

In summary, serialization is necessary to convert data into a standardized format that can be transmitted over the web and interpreted by different systems and programming languages. This is essential for building interoperable applications, like a Spring Boot backend and a React.js frontend.

Deserialization

Deserialization is the process of converting a serialized data format, such as JSON, back into an object that can be easily manipulated and understood by the application. In the case of a React.js frontend receiving data from a Spring Boot backend, the data is typically serialized as JSON by the backend and then deserialized by the frontend.

To deserialize data in React.js, you can use the built-in JSON.parse() method or a third-party library like axios or fetch-jsonp. Here’s an example of how to use JSON.parse() to deserialize a JSON response from a Spring Boot backend: ```sh fetch(‘/api/books’) .then(response => response.json()) .then(data => { // parse the JSON data into a JavaScript object const books = JSON.parse(data);

// do something with the deserialized data
console.log(books);   }); ``` > In this example, the fetch() function is used to make an HTTP request to the Spring Boot backend and receive a JSON response. The response.json() method is called to convert the response into a JSON string, which can then be parsed using JSON.parse() into a JavaScript object. Once the data is deserialized, it can be manipulated and used in the React.js application as needed.

Alternatively, if you’re using a third-party library like axios or fetch-jsonp, deserialization may be handled automatically by the library, depending on how it’s configured. For example, with axios, you can set the responseType property to json to automatically deserialize JSON responses: ```sh axios.get(‘/api/books’, { responseType: ‘json’ }) .then(response => { // the data has already been deserialized into a JavaScript object const books = response.data;

// do something with the deserialized data
console.log(books);   });
> In summary, deserialization is the process of converting a serialized data format, such as JSON, back into an object that can be easily manipulated and understood by the application. In React.js, you can use the built-in JSON.parse() method or a third-party library like axios or fetch-jsonp to deserialize JSON responses from a Spring Boot backend.

#### response.json()
> The response.json() method in the frontend is used to extract the JSON data from an HTTP response that was received from a server. When you make an HTTP request using the fetch() method or a similar API, you receive a response object that contains information about the response, such as the status code and any headers. However, to access the actual JSON data that was returned by the server, you need to extract it from the response body.

> The response.json() method is a built-in method in JavaScript's Response interface that extracts the JSON data from the response body and returns it as a JavaScript object. The method reads the response body and parses it as JSON, and then returns the resulting object.

> Here's an example of how to use response.json() to extract JSON data from a response object:

```sh
fetch('https://example.com/api/data')
  .then(response => response.json())
  .then(data => {
    // use the parsed JSON data here
    console.log(data);
  });

In this example, we make an HTTP request to the https://example.com/api/data URL using the fetch() method. The then() method is used to handle the response once it is received. The response.json() method is called to extract the JSON data from the response body, and the resulting object is passed to the next then() method for further processing.

Using response.json() is important because it allows you to work with the JSON data in a JavaScript-friendly format, rather than having to parse it manually or work with it as a string. Once the JSON data has been parsed into a JavaScript object, you can easily manipulate and use it in your code.

JSON.parse()

Not all data sent from the backend to the frontend needs to be parsed using JSON.parse().

JSON (JavaScript Object Notation) is a commonly used format for sending data between the backend and frontend because it is lightweight, easy to read and write, and can be easily parsed by JavaScript.

If the data being sent is already in JSON format, it can be directly sent from the backend to the frontend and received in the frontend using fetch() or any other HTTP request library. The response from the backend will already be in JSON format, so it can be directly used in the frontend JavaScript code without the need for parsing it using JSON.parse().

However, if the data being sent is not in JSON format, such as plain text or binary data, then it cannot be directly used in the frontend JavaScript code. In this case, it needs to be transformed into a format that can be used by the frontend JavaScript code, such as parsing plain text data as a string, or using a binary parser to parse binary data.

Backend code using JSON format ```sh @RestController public class BookController {

@GetMapping("/books")
public List<Book> getBooks() {
    List<Book> books = new ArrayList<>();
    // code to fetch books from database
    return books;
} } ``` > Frontend code using fetch() and JSON.parse(): ```sh fetch('/books')
.then(response => response.json())
.then(data => {
    console.log(data); // data will be a parsed JSON object
    // code to process data
})
.catch(error => console.error(error)); ``` > Here's an example where you need to use JSON.parse() after using response.json(): > Let's say the backend sends data to the frontend in JSON format like this: ```sh {
"bookId": 1234,
"title": "The Great Gatsby",
"author": "F. Scott Fitzgerald" } ``` > If you retrieve this data in the frontend using fetch() and response.json(), the response will be a JavaScript object. However, let's say you need to store this object as a string in local storage. To do this, you need to convert the object to a JSON string using JSON.stringify(). But when you retrieve the data from local storage, you will get a string, and you need to convert it back to a JavaScript object using JSON.parse(): ```sh // Get book data from backend fetch('/books/1234')
.then(response => response.json())
.then(data => {
    const bookData = JSON.stringify(data);
    localStorage.setItem('bookData', bookData);
    // code to process book data
})
.catch(error => console.error(error));

// Retrieve book data from local storage const bookData = localStorage.getItem(‘bookData’); const book = JSON.parse(bookData); console.log(book.title); // output: “The Great Gatsby”

> Here, the response is first converted to a JavaScript object using response.json(). The object is then converted to a JSON string using JSON.stringify() and stored in local storage. When the data is retrieved from local storage using localStorage.getItem(), it is a string and needs to be converted back to a JavaScript object using JSON.parse().

#### String is the Boss
> When sending data over the web from a backend to a frontend, the data is typically serialized into a text-based format like JSON. In JSON, all data is represented as strings, even if the original data was a number, boolean, or other type. This means that when you send an integer value from a backend to a frontend using JSON serialization, the integer value will be converted into a string representation of the number during the serialization process.

> However, this does not mean that you can only pass data in the form of strings from a backend to a frontend. When the data is received on the frontend, you can easily convert the string representation of the data back into its original type using appropriate JavaScript methods like parseInt() or parseFloat() for numbers, JSON.parse() for JSON data, or other parsing methods for other data types.

> For example, let's say you are sending a JSON object containing an integer value and a string value from a Spring Boot backend to a React.js frontend:
```sh
@GetMapping("/api/data")
public ResponseEntity<Map<String, Object>> getData() {
    Map<String, Object> data = new HashMap<>();
    data.put("intValue", 42);
    data.put("stringValue", "Hello, world!");
    return ResponseEntity.ok(data);
}

In this example, we define a GET endpoint /api/data in our Spring Boot backend that returns a JSON object containing an integer value of 42 and a string value of “Hello, world!” as the response body.

On the React.js side, you can then use the response.json() method or a third-party library like axios or fetch-jsonp to extract the JSON data from the response. Once you have the JSON data, you can access the integer value and the string value as follows:

fetch('https://example.com/api/data')
  .then(response => response.json())
  .then(data => {
    const intValue = parseInt(data.intValue); // Convert the string to an integer
    const stringValue = data.stringValue; // No conversion necessary
    console.log(intValue); // Outputs 42
    console.log(stringValue); // Outputs "Hello, world!"
  });

In this example, we use parseInt() to convert the string representation of the integer back into an actual integer value, and we simply access the string value as a string.

So, in summary: while data is typically serialized into a text-based format like JSON when sending data from a backend to a frontend, you can still send and receive data of various types, including integers, booleans, strings, arrays, and objects. While the data will be represented as strings during transmission, you can easily convert the string representation back into the original data type using appropriate JavaScript methods on the frontend.

Different ways to send data from backend to frontend

To extract a specific cookie value from this string, we need to split the string into an array of individual cookies using the semicolon and space as the separator. We can then use the Array.find() method to search for the cookie that we are interested in. However, the cookie name and value are usually separated by an equals sign (“=”).

So we split the cookie string into an array of individual cookies using cookies.split(‘;’). Then, we use the Array.find() method with a callback function that checks if each cookie starts with the name of the cookie we are interested in (bookId). If a match is found, the find() method returns the matching cookie as a string.

We then use the String.trim() method to remove any leading or trailing whitespace from the cookie string, and the String.startsWith() method to check if the cookie starts with “bookId=”. If this is true, we have found the cookie that we are interested in, and we can extract the value of the cookie by splitting the string again at the equals sign (“=”) and taking the second element of the resulting array.

const socket = new SockJS('/websocket');
const stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
    stompClient.subscribe('/user/queue/book/123', function(message) {
        const book = JSON.parse(message.body);
        // do something with book object
    });
});

In this example, the frontend establishes a Websocket connection with the backend, subscribes to the book with ID 123, and receives the book object as a message.

eventSource.onmessage = function(event) { const receivedMessage = event.data; // Process the received message console.log(“Received message from server: “ + receivedMessage); };

> In this example, we define a REST endpoint on the backend that returns a stream of text event data using the MediaType.TEXT_EVENT_STREAM_VALUE value for the produces attribute. This REST endpoint uses a Flux to emit a message every second.

> On the frontend, we create a new EventSource object and connect to the backend's REST endpoint using the EventSource constructor. We then define an event listener for incoming messages. When a message is received, we can process it as needed.

> Note that Server-Sent Events are a one-way communication protocol, which means that the backend can send messages to the frontend, but the frontend cannot send messages back to the backend using this protocol.

- Push notifications
> The backend can send push notifications to the frontend, which are displayed as notifications on the user's device or browser. This is often used for real-time updates or alerts.
```sh
@RestController
public class MyRestController {
    private final FirebaseMessaging firebaseMessaging;

    public MyRestController(FirebaseMessaging firebaseMessaging) {
        this.firebaseMessaging = firebaseMessaging;
    }

    @PostMapping("/send-push-notification")
    public void sendPushNotification(@RequestBody PushNotificationRequest request) throws FirebaseMessagingException {
        Message message = Message.builder()
                .setNotification(Notification.builder()
                        .setTitle(request.getTitle())
                        .setBody(request.getBody())
                        .build())
                .setToken(request.getDeviceToken())
                .build();
        firebaseMessaging.send(message);
    }
}
const messaging = firebase.messaging();
messaging.requestPermission().then(() => {
    console.log("Notification permission granted.");

    messaging.getToken().then((token) => {
        console.log("Device token:", token);
        // Send the device token to the backend
        sendDeviceTokenToBackend(token);
    }).catch((err) => {
        console.log("Error getting device token:", err);
    });
}).catch((err) => {
    console.log("Error requesting notification permission:", err);
});

messaging.onMessage((payload) => {
    console.log("Received message from server:", payload);
    // Process the received message
});

In this example, we use Firebase Cloud Messaging (FCM) to send push notifications from the backend to the frontend. On the backend, we define a REST endpoint that accepts a PushNotificationRequest object as the request body. This object contains the title, body, and device token of the recipient device. We use the FCM FirebaseMessaging object to send a message to the specified device using the send() method.

On the frontend, we use the Firebase JavaScript SDK to request permission to receive push notifications and to retrieve the device token. We then send the device token to the backend so that it can send push notifications to this device in the future. When a push notification is received, the messaging.onMessage() event listener is triggered, and we can process the received message as needed.

Frontend to Backend

To send data from a React.js frontend to a Spring Boot backend, you can use HTTP methods like POST, PUT, or DELETE. Typically, you would use a form or an AJAX request to send the data to the backend.

Here is an example of sending data from a React.js component using an AJAX request with fetch(): ```sh const data = { name: ‘John Doe’, age: 30 };

fetch(‘https://example.com/api/users’, { method: ‘POST’, headers: { ‘Content-Type’: ‘application/json’ }, body: JSON.stringify(data) }) .then(response => response.json()) .then(data => { console.log(‘Success:’, data); }) .catch((error) => { console.error(‘Error:’, error); });

> In this example, we are sending a POST request to the /api/users endpoint with some data in the request body. The JSON.stringify() method is used to convert the data object to a JSON string before sending it to the backend. The headers property is set to specify that we are sending JSON data in the request body.

> On the Spring Boot backend, you can define an endpoint that handles the request and extracts the data from the request body as follows:
	
```sh 
@PostMapping("/api/users")
public ResponseEntity<User> createUser(@RequestBody User user) {
    // Handle the user data here...
    return ResponseEntity.ok(user);
}

In this example, we define a POST endpoint /api/users in our Spring Boot backend that accepts a User object as the request body. Spring Boot will automatically deserialize the JSON data in the request body into a User object, which we can then use to create a new user in the backend. Finally, we return the User object in the response body.

Note that you will need to ensure that the User class implements the Serializable interface in order for Spring Boot to properly deserialize the JSON data in the request body into a User object. Also, make sure to handle any validation or error scenarios appropriately in your backend code.

JSON.stringify(data)

In order to send data from a frontend application to a backend API, the data needs to be in a format that can be transmitted over the network. One common format for sending data over the web is JSON (JavaScript Object Notation), which is a text-based data format that is easy to read and write.

However, in order to send data as JSON, it needs to be converted from a JavaScript object into a JSON string. This is where the JSON.stringify() method comes in.

The JSON.stringify() method takes a JavaScript object and returns a JSON string representation of that object. This allows us to send the data to the backend in a format that can be easily parsed and understood.

For example, let’s say we have a JavaScript object like this:

const data = { name: 'John', age: 30 };

If we want to send this data to the backend API as JSON, we can use JSON.stringify() to convert it to a JSON string:

const jsonData = JSON.stringify(data);	

This will result in a JSON string that looks like this:

{"name":"John","age":30}

We can then send this JSON string to the backend API using an AJAX request, and the backend can parse the JSON data and use it as needed.

In summary, we use JSON.stringify() to convert JavaScript objects to JSON strings so that we can send the data over the network to the backend API.

Different ways to send data from frontend to backend