Playframework - display Json in a view - json

i'm facing to the compilation error "unspecified value parameter content" when i try to send json node to a view. The error occurs on the line 3 of bo.scala.html.
Thanks for helping
in my controller - Application.java
//send jsonNode to view table
public static Result showReportsUniverses() throws SDKException {
ArrayList<BiObjectsInfos> boobjects = BiFunctions.getReportsUniverses(user,
password, cms, apsAuthType);
return ok(bo.render(Json.toJson(boobjects)));
}
My routes
GET /boobjects controllers.Application.showReportsUniverses()
My view - bo.scala.html -
#()
#table(){
// boobjects handles the JsonNode boobjects
<script src="#routes.Assets.at("javascripts/boobjects.js")" type="text/javascript"></script>
<tbody id= "boobjects" \>
<tr>
<th>Reports</th>
<th>Universes</th>
}
My view - table.scala.html -
#(content : Html)
<!DOCTYPE html>
<html>
<head>
<title>Bla</title>
<link rel="stylesheet" href="#routes.Assets.at("css/table.css")" >
<script src="#routes.Assets.at("javascripts/jquery-1.11.1.min.js")" type="text/javascript"></script>
</head>
<body>
<table>
#content
</table>
</body>
</html>
my coffee script boobjects.js
$ ->
$.get "/boobjects", (boobjects) ->
$.each boobjects, (index, boObj) ->
$("#boobjects").append $("<tr>")
$("#boobjects").append $("<td>").text boObj.si_name
$("#boobjects").append $("<td>").text boObj.universe_name

return ok(boobjects.render(toJson(boobjects)));
should read
return ok(boobjects.render(Json.toJson(boobjects)));

Related

Is there a way to inline a Spring MVC model attribute in JSON in thymeleaf for an html attribute?

Okay, So, I have a model object that we will call Station, with a list of codes associated.
class Station {
public List<String> codes;
}
I have a controller method which render a view showing the list of a station.
class StationController {
#Autowired
private StationService stationService;
#GetMapping()
public String showAllStations(Model model) {
model.addAttribute("stations", stationService.getAllStations())
return "stationsView"
}
}
Here is my template
<html xmlns:th="http://www.thymeleaf.org">
<body>
<div th:each="station : ${stations}" th:text="${station.codes}">
</div>
</body>
</html>
So, let's say my first station as two codes, CD1 et CD2. The rendered html will be the following :
<html xmlns:th="http://www.thymeleaf.org">
<body>
<div>[CD1, CD2]</div>
...Skipping the additional divs.
</body>
</html>
Is there a way to render the codes as a JSON array ? I know thymeleaf can do it in javascript, using inline.
For example,
<script type="text/javascript" th:inline="javascript">
/*<![CDATA[*/
var data = [[${renter.sabreCodes}]];
/*]]>*/
</script>
will be rendered as
<script type="text/javascript" th:inline="javascript">
/*<![CDATA[*/
var data = ["CD1","CD2"];
/*]]>*/
</script>
So I would want the same result for an attribute value.
Of course, I have a lot of workaround for this, but I would want to know if these workaround are needed, or if it just me who don't know how to get straight to the point.

Thymeleaf cannot resolve static ressources when using SpringMVC's #PathVariable

somehow my CSS-file is not included into my thymeleaf-template.
First of all I need to explain the workflow:
User clicks on form-Submit to send a POST to /historyDetails/{history_id}
Some data will be fetched from database using the history_id
The data will be rendered on history-detail-view.html
This is my DispatcherServlet:
#Configuration
#EnableWebMvc
#ComponentScan("*")
public class DispatcherServlet extends WebMvcConfigurerAdapter {
#Autowired
private WebApplicationContext ctx;
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
/*
* resolve path to static ressources (images, stylesheets, javascript-files)
*/
registry.addResourceHandler("img/**").addResourceLocations("/WEB-INF/static/img/");
registry.addResourceHandler("css/**").addResourceLocations("/WEB-INF/static/css/");
registry.addResourceHandler("js/**").addResourceLocations("/WEB-INF/static/js/");
}
#Bean
public ThymeleafViewResolver getViewResolver() {
ThymeleafViewResolver vr = new ThymeleafViewResolver();
vr.setTemplateEngine(getTemplateEngine());
return vr;
}
#Bean
public SpringTemplateEngine getTemplateEngine() {
SpringTemplateEngine te = new SpringTemplateEngine();
te.setTemplateResolver(getTemplateResolver());
te.setEnableSpringELCompiler(true);
return te;
}
#Bean
public SpringResourceTemplateResolver getTemplateResolver() {
SpringResourceTemplateResolver tr = new SpringResourceTemplateResolver();
tr.setApplicationContext(ctx);
tr.setOrder(1);
/*
* resolve path to html to WEB-INF/<name>.html
*
* name can be something like templates/xxx.html
*/
tr.setPrefix("WEB-INF/");
tr.setSuffix(".html");
return tr;
}
}
My projectstructure (from root-directory):
This is the htistory-detail-view.html:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet"
type="text/css"
th:href="#{css/style.css}"/>
<script type="text/javascript"
th:src="#{https://code.jquery.com/jquery-3.4.1.min.js}"></script>
<script type="text/javascript"
th:src="#{js/utilities.js}"></script>
</head>
<body>
<div th:replace="fragments/grid :: grid(${grid}, 'HISTORY_DETAIL')"></div>
<div th:replace="fragments/paging :: paging(${grid})"></div>
</body>
<div th:replace="fragments/general :: footer"></div>
</html>
While the index.html is rendered with css, the history-detail-view.html is not but rather plain html.
The only errormessage, which I took from the network-tab in firefox is:
Loading failed for the <script> with source “http://localhost:9080/MyProject/historyDetails/js/utilities.js”.
The reason why I put the DispatcherServlet into this thread is becouse it is responsible for resolving the paths to the static ressources. When comparing the path from the projectstructure with the path in the errormessage, the DispatcherServlet doesn't seem to work properly but I don't know how to make it resolve the correct path.
The only difference I see here is the Pathvariable.
EDIT: I'm providing my index.html, since it is working properly here:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet"
type="text/css"
th:href="#{css/style.css}"/>
<script type="text/javascript"
th:src="#{https://code.jquery.com/jquery-3.4.1.min.js}"></script>
<script type="text/javascript"
th:src="#{js/utilities.js}"></script>
</head>
<body>
<div th:replace="fragments/grid :: grid(${grid}, 'HISTORY')"></div>
<div th:replace="fragments/paging :: paging(${grid})"></div>
</body>
<div th:replace="fragments/general :: footer"></div>
</html>
The issue might be because of the spring security configuration if any. Add the path to your CSS static files as an exception in the spring security configuration.
If you are not using spring security or that you have provided the exception, make sure you have followed the standard folder structure.
Go through this link for more details.

What are SERVICE_AUTH_URL and SERVICE_AUTH_TOKEN_URL in Gmail Add-ons?

This is Google's code
function getOAuthService() {
return OAuth2.createService('SERVICE_NAME')
.setAuthorizationBaseUrl('SERVICE_AUTH_URL')
.setTokenUrl('SERVICE_AUTH_TOKEN_URL')
.setClientId('CLIENT_ID')
.setClientSecret('CLIENT_SECRET')
.setScope('SERVICE_SCOPE_REQUESTS')
.setCallbackFunction('authCallback')
.setCache(CacheService.getUserCache())
.setPropertyStore(PropertiesService.getUserProperties());
}
I don't know what are SERVICE_AUTH_URL and SERVICE_AUTH_TOKEN_URL
This is my
var SERVICE_AUTH_URL = 'http://account.simontest.com/a/login?app=addon';
After submit and login, I redirect my website to this link:
https://script.google.com/macros/d/13-mVZUel3ZnYoFKC5JrRUkWD12iMSa3REEfddfdf71ucXm1rA_s0/usercallback
and got this message :
"Sorry, unable to open the file at this time.
Please check the address and try again."
https://imgur.com/a/C8Iep
But It's still error.
Anybody has any idea about where I am going wrong? Thanks.
Here, SERVICE_AUTH_TOKEN_URL is the rest api url of the service to get the access token, refresh token using auth code generated in the oauth login process. Probably, you might have missed the callback implementation.Follow the below code:
var oauthService = getOAuthService();
function authCallback(oauthResponse) {
try {
console.log("oauthResponse->" + JSON.stringify(oauthResponse));
oauthService.handleCallback(oauthResponse);
return HtmlService.createHtmlOutputFromFile("auth-success");
} catch (e) {
var template = HtmlService.createTemplateFromFile("auth-failure");
template.errorMessage = e.toString();
return template.evaluate();
}
}
auth-success.html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
</head>
<body>
<div class="sidebar">
<p>Your GitHub account has been connected.</p>
</div>
</body>
<script>
setTimeout(function() {
top.window.close();
}, 2000);
</script>
</html>
auth-failure.html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
</head>
<body>
<div class="sidebar">
<p>Your GitHub account was not connected. Please try again.</p>
<h3>Details:</h3>
<pre><?= errorMessage ?></pre>
</div>
</body>
</html>
I kept getting the "Sorry, unable to open the file at this time." message until I realized you have to append a secret access code as well as the state to the url.
The OAuth2 server (account.simontest.com in your case) needs to format the redirect url like this:
Pseudo-code:
$redirect_uri = $redirect_uri . "?code=" . $your_secret_code . "&state=" . $state
See this page for more details: OAuth2 Simplified

What's wrong with my FLOT data?

My PHP is working fine and I appear to be getting back the correct JSON data for FLOT, but I'm still getting a blank chart :-/
Here's the PHP:
foreach($result as $row) { //or whatever
$dataset1[] = array((int) $row['INDX'], (int) $row['RUNTIME'] );
}
echo json_encode($dataset1);
Here's a sample of the JSON it returns:
[[31,2303],[113,5697],[201,4485],[151,4404],[192,2668],[84,1082],[13,6003],[68,3628],[12,2115]]
Here's the function to plot:
$(function () {
$.plot($("#dashboard_div"), apudata);
console.log(apudata);
});
The console log shows correctly formatted JSON as above. I can cut and paste from the console log into a literal variable for that function and it works, but passing the JSON as a variable doesn't.
Ideas?Help?
Try using the code below. Set the 1000 (ms) interval to however often you want the graph to update. This is simply (very slightly edited) code from one of my previous posts that I put in the comments.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>AJAX FLOT</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.time.js"></script>
</head>
<body>
<div id="placeholder" style="width: 100%;height: 600px;"></div>
<div id="div" style="width: 100%; height: 100px;"></div>
<script type="text/javascript">
var options = {
lines: {
show: true
},
points: {
show: true
},
xaxis: {
mode: "time"
}
};
window.setInterval(function(){
$.getJSON('http://localhost/data.php', function (csv) {
dataOne = csv;
var plot = $.plot($('#placeholder'), [dataOne], options);
});
}, 1000);
</script>
</html>
Not sure if it matters, but the flot docs say to just pass the selector as a string to $.plot(), and not a jQuery object. So instead of
$.plot($('#dashboard_div'), apudata);
try
$.plot('#dashboard_div', apudata);

ngTable / Angular with external JSON data, buttons not showing

I know there's quite a lot of info already on stackoverflow regarding ngTable/AngularJS, but I tried everything, and it just doesn't work.
my html is this:
<!doctype html>
<html lang="en" >
<head>
<meta charset="utf-8">
<title>Sequencing experiments overview</title>
<script src="/LIMS/angular-1.2.14/angular.js"></script>
<script src="/LIMS/js/controllers.js"></script>
<script src="/LIMS/ng-table-master/ng-table.js"></script>
<link rel="stylesheet" href="/LIMS/ng-table-master/ng-table.css" />
<link data-require="bootstrap-css#*" data-semver="3.0.0" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" />
<link rel="stylesheet" href="/LIMS/style.css" />
</head>
<body ng-app="dataOverview" ng-controller="searchCtrl">
<div>
Search: <input ng-model="query">
<p><strong>Page:</strong> {{tableParams.page()}}
<p><strong>Count per page:</strong> {{tableParams.count()}}
<table ng-table="tableParams" class="table">
<tr ng-repeat="exp in $data | filter:query">
<td data-title="'id'">
{{exp.id}}
</td>
<td data-title="'name'" sortable ="'name'">
{{exp.name}}
</td>
<td data-title="'Type'">
{{exp.type}}
</td>
</tr>
</table>
</div>
</body>
</html>
my controller.js file is this:
var dataOverview = angular.module('dataOverview', ['ngTable']);
dataOverview.controller('searchCtrl', function searchCtrl($scope, $http, ngTableParams) {
$scope.tableParams = new ngTableParams({
page: 1, // show first page
count: 5 // count per page
},{
getData: function($defer,params) {
$http.get('/LIMS/index_query.php').
success(function(data, status) {
var orderedData = data;
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(),params.page() * params.count()));
})
}
})
});
The index_query.php returns a valid JSON object queried from a MySQL DB (will not show this here).
So, this code is almost ok i guess. It displays a table with columns and values from the DB. I can filter using the value in the filter box. However, it only shows 5 rows, and there are no buttons to go to the next 5 rows or increase the number of rows on the page. As described on the ngTable page (http://bazalt-cms.com/ng-table/example/1).
When checking console with firebug, I see an 'Uncaught TypeError: Cannot call method 'push' of undefined ' error. I assume it;s an error populating the array which should build the buttons to go from 1 page with 5 records to another? I wasted 10h on this today, so please enlighten me, I would be very grateful.