0
votes

I'm building a JHipster Monolithic application with React. In the Backend, I can use the application.yml / ApplicationProperties.java to add properties (such as API keys) which may change between environments (Dev, Prod etc).

My question is, can I do the same thing on the React front-end? This is a Spring application so the same application.yml and ApplicationProperties.java are in place. Does anyone have a code example of surfacing custom properties to the UI?

I have read the answer from this post (JHipster React Front End (Gateway) Application Properties) but it did not help me because it is a monolithic application in my case.

1

1 Answers

3
votes

The solution from the other post works for a monolith. For a full solution, see below:

First, make sure you have configured the config you want exposed. Also configure it in ApplicationProperties.java (or set ignoreUnknownFields to false):

application:
  my-value: 'TestValue'

Create a REST endpoint for exposing the config value to the client (modified from the other answer):

package com.mycompany.myapp.web.rest;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Resource to return custom config
 */
@RestController
@RequestMapping("/api")
public class CustomConfigResource {

    @Value("${application.my-value:}")
    private String myValue;

    @GetMapping("/custom-config")
    public CustomConfigVM getCustomConfig() {
        return new CustomConfigVM(myValue);
    }

    class CustomConfigVM {
        private String myValue;

        CustomConfigVM(String myValue) {
            this.myValue = myValue;
        }

        public String getMyValue() {
            return myValue;
        }

        public void setMyValue(String myValue) {
            this.myValue = myValue;
        }
    }
}

Create a reducer to fetch and store the information:

import axios from 'axios';

import { SUCCESS } from 'app/shared/reducers/action-type.util';

export const ACTION_TYPES = {
  GET_CONFIG: 'customConfig/GET_CONFIG',
};

const initialState = {
  myValue: '',
};

export type CustomConfigState = Readonly<typeof initialState>;

export default (state: CustomConfigState = initialState, action): CustomConfigState => {
  switch (action.type) {
    case SUCCESS(ACTION_TYPES.GET_CONFIG): {
      const { data } = action.payload;
      return {
        ...state,
        myValue: data['myValue'],
      };
    }
    default:
      return state;
  }
};

export const getConfig = () => ({
  type: ACTION_TYPES.GET_CONFIG,
  payload: axios.get('api/custom-config'),
});

Finally, call the reducer's getConfig method from a component, for example in App.tsx:

import { getConfig } from 'app/shared/reducers/custom-config';
...
useEffect(() => {
    props.getConfig();
  }, []);
...
const mapDispatchToProps = { getConfig };
...