user2488401
user2488401

Reputation:

How to Pass JSF Bean data to JavaScript Function?

I am passing data with the below code:

<p:poll interval="3" listener="#{chartController.loadChartData}" oncomplete="renderChart('container','area','Sample Chart', '#{chartController.chartData}', '#{chartController.categories}');" 
                      id="chartvalue_btn" update="textID" />

But when I checked null value is passed in JavaScript function while I checked bean variable initialized with values. Am I doing something wrong here? ANd my bean is

package com.bchetty.charts.controller;

import com.bchetty.charts.model.Series;
import com.google.gson.Gson;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.bean.ViewScoped;

/**
 * Chart Controller
 */
@ManagedBean(name="chartController")
@SessionScoped
public class ChartController {
    private String chartData;
    private String categories;
    private List<String> categoryList = new ArrayList<String>();
    private List<Long> heapSizeList = new ArrayList<Long>();
    private List<Long> usedHeapSizeList = new ArrayList<Long>();
    SimpleDateFormat sdfDate = new SimpleDateFormat("HH:mm:ss");//dd/MM/yyyy
    private static final long MB = 1024*1024;
    int index = 0;
    private Long[] longs;

    /**
     * Load Chart Data
     */
    public void loadChartData() {
        if(heapSizeList.size() > 10) {
            heapSizeList.remove(0);
            usedHeapSizeList.remove(0);
            categoryList.remove(0);
        }
        List<Series> series = new ArrayList<Series>();

        malloc();
        long heapSize = Runtime.getRuntime().maxMemory();
        heapSizeList.add(heapSize/MB);
        usedHeapSizeList.add((heapSize - Runtime.getRuntime().freeMemory())/MB);

        series.add(new Series("Heap Size", heapSizeList));
        series.add(new Series("Used Heap", usedHeapSizeList));

        setChartData(new Gson().toJson(series));

        categoryList.add(sdfDate.format(new Date()));
        System.out.println(categoryList);

        setCategories(new Gson().toJson(categoryList));
    }

    /**
     * @return the chartData
     */
    public String getChartData() {
        return chartData;
    }

    /**
     * @param chartData the chartData to set
     */
    public void setChartData(String chartData) {
        this.chartData = chartData;
    }

    /**
     * @return the categories
     */
    public String getCategories() {
        return categories;
    }

    /**
     * @param categories the categories to set
     */
    public void setCategories(String categories) {
        this.categories = categories;
    }

    private void malloc() {
        if(index%2 == 0) {
            longs = new Long[100000];
            for(int i=0;i<1000;i++) {
                longs[i] = Long.valueOf(i);
            }
        } else {
            longs = null;
        }
        index++;
    }
}

Upvotes: 2

Views: 3142

Answers (1)

user1983983
user1983983

Reputation: 4841

The problem is that the arguments of the oncomplete-function are only updated when the view is entered. The arguments are not automatically updated when the value of the properties on the bean have changed. So as chartController.chartData is initially not instanciated it is null when the page is rendered and remains null until you manually refresh the whole page.

To fix this issue I would recommend you to use the Primefaces RequestContext and add the chartData everytime loadChartData is called as a callback param. I.e. add the following to the and of loadChartData:

public void loadChartData() {
    ...
    RequestContext context = RequestContext.getCurrentInstance();
    context.addCallbackParam("chartData", chartData);
    context.addCallbackParam("categories", categories);
}

And in the UI define the p:poll as follows:

<p:poll interval="3" listener="#{chartController.loadChartData}"
    oncomplete="renderChart('container','area','Sample Chart', args.chartData, args.categories);"
    id="chartvalue_btn" update="textID" />

If this is no option for you, because you are using loadChartData anywhere else, wrap the call of loadChartData with the addCallbackParam stuff in another method and specify this method as listener of the p:poll.

Upvotes: 2

Related Questions