Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

com.chuklee.code:statetransfer

Package Overview
Dependencies
Maintainers
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

com.chuklee.code:statetransfer

Angular Universal supports state transfer from server to client; state transfer allows the server to embed startup data into the client. The Angular client can retrieve this embedded data rather than making a XHR call to the server. See https://angular.io/api/platform-browser/TransferState This is a utility library for injecting states into Angular application from within a Java application. It does not support full Angular Universal features like service injection and rendering views.

  • 0.1
  • Source
  • Maven
  • Socket score

Version published
Maintainers
1
Source

statetransfer - Server-side Java to Angular state transfer library

Angular Universal supports state transfer from server to client; state transfer allows the server to embed startup data into the client. The Angular client can retrieve this embedded data rather than making a XHR call to the server. See [https://angular.io/api/platform-browser/TransferState] (https://angular.io/api/platform-browser/TransferState)

This is a utility library for injecting states into Angular application from within a Java application. It does not support full Angular Universal features like service injection and rendering views.

Quick Start

Use case: we would like to generate a string on the server (Spring Boot) and embed that in the Angular application.

List of things to prepare

  • An application id that identifies the application eg. myapp
  • One or more unique state keys; the values that are to be transferred are in a map. The are keys are used to access them: eg. title, user
  • A name to render the serialized state in index.html eg. serialized_state

Step 1 - Generate a Spring Boot Application

Generate a Spring Boot application; add Thymeleaf and Spring Web as dependencies. Once the project has been generated update pom.xml with the following 2 dependencies:

<dependencies>
	...
	<dependency>
		<groupId>com.chuklee.code</groupId>
		<artifactId>statetransfer</artifactId>
		<version>0.1</version>
	</dependency>

	<dependency>
		<groupId>org.glassfish</groupId>
		<artifactId>jakarta.json</artifactId>
		<version>2.0.1</version>
	</dependency>
</dependencies>

This utility library uses JSON-P to hold values.

Step 2 - Create a MVC Controller

The controller should process all GET request to either / or /index.html. What this mean is that the complied Angular application should be save in static and templates directories.

You can remap this according to your requirements.

package com.acme;

import java.util.Date;

import com.chuklee.code.statetransfer.TransferState;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import jakarta.json.Json;
import jakarta.json.JsonObject;
import jakarta.json.JsonString;

@Controller
@RequestMapping(path={"/", "/index.html"})
public class IndexController {

	@GetMapping
	public String getIndex(Model model) {

		// Create a state transfer object with the application id
		// This id will identify the Angular application
		TransferState state = new TransferState("myapp");

		// Use JSON-P to create values and objects to be transferred
		// TransferState can transfer any valid JSON object
		// This is a object
		JsonObject user = Json.createObjectBuilder()
			.add("name", "wilma")
			.add("email", "wilma@gmail.com")
			.add("address", "1 bedrock ave")
			.build();
		// This is a string
		JsonString title = Json.createValue("Generated on %s".formatted(new Date()));

		// Add the values and objects to the state
		state.add("user", user);
		state.add("title", title);

		// Render Angular's index.html
		model.addAttribute("serialized_state", state.render());

		return "index";
	}
}

Now we need to compile an Angular application.

Step 3 - Generate an Angular Application

Create a new Angular application if you don't have one. Use ng new client to generate an angular application.

Step 4 - Import State Transfer Modules

Modify the startup module (default is app.module.ts) to import BrowserTransferStateModule. You will also need to register the application id.

import { NgModule } from '@angular/core';
import { BrowserModule, BrowserTransferStateModule } from '@angular/platform-browser';

import { AppComponent } from './app.component';

@NgModule({
	declarations: [ 
		AppComponent
	],
	imports: [
		// appId must be the same value when you instantiated TransferState
		BrowserModule.withServerTransition({ appId: 'myapp' }),
		BrowserTransferStateModule
	],
	providers: [],
	bootstrap: [AppComponent]
})
export class AppModule { }

Step 5 - Access the Transferred States from the Component

We will transfer a string (title) and an object (user) from the server. The following is an example of app.component.ts.

import { Component, OnInit } from '@angular/core';
import {makeStateKey, TransferState} from '@angular/platform-browser';

// This is object to to be transferred from the server. 
// Should match the server's structure
export interface User {
	name: string
	address: string
	email: string
}

// Create state keys. The key names must match the server's
const stateTitleKey = makeStateKey<string>('title')
const stateUserKey = makeStateKey<User>('user')

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
	title = 'client';
	user: User = {
		name: 'fred', address: '1 bedrock ave', email: 'fred@gmail.com' 
	}

	// Inject TransferState service
	constructor(private state: TransferState) { }

	ngOnInit() {
		// Get the transferred state; if the states are missing, then
		// revert to default values. It is important that we should be
		// able to render the view without the server states
		this.title = this.state.get(stateTitleKey, 'client')
		this.user = this.state.get(stateUserKey, this.user)
	}
}

Access these in the view app.component.html

<h1>{{ title }}</h1>
<h2>{{ user | json }}</h2>

Step 6 - Inject the Serialized State

Add a placeholder in Angular's index.html to serialize the state. When the final index.html is rendered by the server side template engine, it will populate the placeholder with serialized data.

How the placeholder is written will depend very much on which template engine you are using. In this example, I will be using (Thymeleaf)[https://www.thymeleaf.org/] specifically (inline unescaped text)[https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#inlining].

<!doctype html>
<html lang="en">
	<head>
		<meta charset="utf-8">
		<title>Client</title>
		<base href="/">
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<link rel="icon" type="image/x-icon" href="favicon.ico">

		<!-- this is the placeholder -->
		[(${serialized_state})]
	</head>
	<body>
		<app-root></app-root>
	</body>
</html>

You can add the placeholder anywhere in index.html but <head> is probably the best because if the application is not served from the server, then the placeholder will not appear in your view.

Step 7 - Compile and Transfer Artefacts

Compile the Angular application with ng build. When the build complete, you will find the artefacts in dist/client.

Copy the following files from Angular to Spring Boot

  • From Angular dist/client/index.html to Spring Boot src/main/resources/templates directory
  • All files except index.html from Angular dist/client/ to src/main/resources/static directory

Step 8 - Test the Application

Run mvn spring-boot:run

FAQs

Package last updated on 06 Feb 2022

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc