I need to call an API every 10 seconds and need to refresh the grid with updated data. I read about Polling and Server push, but I cant find the optimal solution in my case.I have tried with @push and a Feederthread (Which handles API request and populate values in grid) but while running the Application, thread is not getting started. Below is my code,
@Route(value = UserNavigation.ROUTE)
@PreserveOnRefresh
@org.springframework.stereotype.Component
public class UserNavigation extends AppLayout {
CCUIConfig config;
@Autowired
public UserNavigation( CCUIConfig config) {
this.config = config;
addToDrawer(createAccordianMenu());
}
private Component createAccordianMenu() {
VerticalLayout scrollableLayout = new VerticalLayout();
Div kioskMonitor_div = new Div(kiosksMonitorLabel);
kioskMonitor_div.addClickListener(event -> {
try {
setContent(new Monitor(config).getDashboard());
} catch (Exception e) {
e.printStackTrace();
}
});
scrollableLayout.add(kioskMonitor_div);
return scrollableLayout;
}
}
@Push
@Route
public class Monitor extends VerticalLayout{
CCUIConfig config;
Grid<Model> grid = new Grid<>();
private FeederThread thread;
public Monitor(CCUIConfig config) {
this.config = config;
}
@Override
protected void onAttach(AttachEvent attachEvent) {
// Start the data feed thread
super.onAttach(attachEvent);
thread = new FeederThread(attachEvent.getUI(),grid);
thread.start();
}
@Override
protected void onDetach(DetachEvent detachEvent) {
thread.interrupt();
thread = null;
}
public Component getDashboard() throws IOException{
String updateddate =null;
VerticalLayout dashboardview = new VerticalLayout();
Grid.Column<Model> idColumn = grid.addColumn(Model::getid)
.setHeader(ID);
Grid.Column<Model> nameColumn = grid.addColumn(Model::getName)
.setHeader(Name);
Grid.Column<Model> memoryColumn = grid.addColumn(Model::getRefreshTime)
.setHeader(Refresh time"));
dashboardview.add(grid);
return dashboardview;
}
}
class FeederThread extends Thread {
private final com.vaadin.flow.component.UI ui;
private final Grid<Model> grid;
private final CCUIConfig config;
private int count = 30;
public FeederThread(com.vaadin.flow.component.UI ui,Grid<Model> grid) {
this.config = new CCUIConfig();
this.ui = ui;
this.grid= grid;
}
@Override
public void run() {
while (count>0){
try {
Thread.sleep(1000);
ui.access(()-> {
System.out.println("Thread Entry ");
try {
StringBuilder jsongrid = HttpClientGetRequestClient.executeUrlGet(config.getRefreshAPI());
ObjectMapper mapper = new ObjectMapper();
List<Model> userlist = new ArrayList<Model>();
String date="";
if(jsongrid!=null)
{
ModelWrapper eh = mapper.readValue(jsongrid.toString(), ModelWrapper.class);
userlist = eh.getMetricsData();
}
if(userlist != null)
{
grid.setItems(userlist);
grid.getDataProvider().refreshAll();
}
}catch(JSONException |JsonProcessingException e) {
e.printStackTrace();
}
});
count--;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
UserNavigation is the page that loads after user login, it contains a sidebar with multiple options(or functionalities). One of the functionality is the Monitor screen. Monitor is the page with a grid where we need to refresh it in 30 seconds. FeederThread is the thread class that calls an API and update the data in the grid asynchronously.
As from the above code, what happens is like
onAttach(AttachEvent attachEvent)
is not getting executed so the grid is not getting displayed on the page, we use vaadin 14, any help will be appreciated