I hope there is few among you who have experience with Jaspersoft Reports and their new visualise.js api
I have a problem with visualise.js not producing report export file. What happens is:
I am able to succsefully load the report through the visualise.js API, it loads and displays on my web page
Export controls load up successfully too, so I have dropdown with export file formats and a button to export the file.
When I click the export button though, the whole page reloads as if the export button was really a submit button and nothing happens.
Occasionally, the export will work and it will produce file. Though there is no pattern to when it will produce the file and when it will fail.
Below is the code I am using for this (I am using plain text auth for testing purposes):
visualize({
auth: {
name: "mylogin",
password: "mypass",
organization: "organization_1"
}
}, function (v) {
var $select = buildControl("Export to: ", v.report.exportFormats),
$button = $("#button"),
report = v.report({
resource: "/FPSReports/journal",
container: "#export",
params: {
"journal_ref": [ "<?php echo $reference; ?>" ],
},
success: function () {
button.removeAttribute("disabled");
},
error : function (error) {
console.log(error);
}
});
$button.click(function () {
console.log($select.val());
report.export({
// export options here
outputFormat: $select.val(),
// exports all pages if not specified
// pages: "1-2"
}, function (link) {
var url = link.href ? link.href : link;
window.location.href = url;
}, function (error) {
console.log(error);
});
});
function buildControl(name, options){
function buildOptions(options) {
var template = "<option>{value}</option>";
return options.reduce(function (memo, option) {
return memo + template.replace("{value}", option);
}, "")
}
var template = "<label>{label}</label><select>{options}</select><br />",
content = template.replace("{label}", name)
.replace("{options}", buildOptions(options));
var $control = $(content);
$control.insertBefore($("#button"));
//return select
return $($control[1]);
}
});
HTML:
<div class="grid">
<div class="grid-8"></div>
<div class="grid-8 center">Export</div>
<div class="grid-8"></div>
</div>
<div class="grid">
<div class="grid-24" id="export"></div>
</div>
The only parameter comes from URI segment (I am using codeigniter framework):
$reference = $this->uri->segment(3, 0);
I have found an answer that seems to work, and has resolved the issue. Posting it here in case anyone else has this specific problem like I did.
In brief:
After spending hours looking at console debug output I have realised that each time I tried to send a request for export a new session would be opened. Without logging out of the previous one. And apparently that is a no-no. I do not know JS very well but from what I understood there was session id mismatch in request. Please feel free to correct me here :)
The solution to this problem (or for example if you are having authentication issues with visualize.js) is very simple. Set the authentication in global config:
visualize.config({
auth: {
name: "superuser",
password: "superuser"
}
});
No matter if you are using tokens or plain text or whatever else auth is available through the api.
Then do your stuff wherever else on your website:
visualize(function (v) {
v("#container1").report({
resource: "/public/Samples/Reports/06g.ProfitDetailReport",
error: function (err) {
alert(err.message);
}
});
});
visualize(function (v) {
v("#container2").report({
resource: "/public/Samples/Reports/State_Performance",
error: function (err) {
alert(err.message);
}
});
});
Everything should work for you as it did for me. This works in version 5.6 and 6.1 of visualize.js.
Further reading and links from my research:
Token based authentication to Jasper reports failing when used with visualize.js
Visualize.js authentication error after second login
http://community.jaspersoft.com/questions/842695/visualizejs-authentication-error
http://community.jaspersoft.com/questions/845886/authentication-error-refresh-credentials-visualizejs
Code example (5.6):
http://jsfiddle.net/TIBCO_JS_Community/sozzq0sL/embedded/
Api samples (6.1):
http://community.jaspersoft.com/wiki/visualizejs-api-samples-v61
Api samples (5.6):
http://community.jaspersoft.com/wiki/visualizejs-api-notes-and-samples-v56
Really hope this will help someone new to Jaspersoft & visualize.js like me.
Related
Good day,
I've been trying to learn a bit of angular and nodejs. I found a tutorial on a realtime chat app and made some few adjustment to some function of the code. But the one aspect that I cannot seem to get right is the ability for the user to post to a feed. The login process works, the user is already logged in but the user can't post. I would also like to be able to get all they data i insert from all the user to show up like a normal feedview will. Please assist.
Here are my files:
FROM MY CONTROLLER HERE IS THE CODE WHEN THE BUTTON IS PRESSED
$scope.postDatatoDd = () => {
appService.httpCall({
url: '/posts',
params: {
'posts': $scope.data.info,
'from_user_id': $scope.data.username
}
})
.then((response) => {
// $scope.$apply();
})
.catch((error) => {
alert(error.message);
});
}
and here is my route file:
this.app.post('/posts', async(request,response) => {
const reqResponse = {}
const data = {
posts : request.body.postDatatoDd,
from_user_id: request.body.username
};
if (data.posts === ''){
reqResponse.error = true;
reqResponse.message = `error, input`;
response.status(412).json(reqResponse);
} else {
const result = await helper.insertFeed(data);
if (result === null) {
reqResponse.error = true;
reqResponse.message = `they was an error.`;
response.status(417).json(reqResponse);
} else {
reqResponse.error = false;
reqResponse.userId = result.insertId;
reqResponse.message = `posted succesfully`;
response.status(200).json(reqResponse);
}
}});
and in my helper file there is this function to insert data:
async insertFeed(params){
try {
return await this.db.query(
`INSERT INTO posts (from_user_id,posts) values (?,?)`,
[params.from_user_id,params.postDatatoDd]
);
} catch (error) {
console.warn(error);
return null;
}
}
On the client side here is the button with :
<label for="postDatatoDd">Post</label>
<input type="text" id="postDatatoDd"
ng-model="data.postDatatoDd"
class="feed form-control"
placeholder="post your data here?"
/>
<button ng-click="postDatatoDd()" class="btn btn-primary">Post</button>
</div>
--- EDIT 1---
Data is being inserted now, but it is receiving the values as (NULL, NULL).
--- EDIT 2 ---
After closely looking at the code and fixing some naming variables the code works fine, the data is being inserted in mysql as it should.
Other than a lot of typos when it comes to the variables reference. The code seem to be fine.
Assuming that you using appservice class somewhere in your code and its functioned, then everything else will work.
You are getting the (NULL, NULL) because you are parsing parameters that are not being properly parsed out to your helper file, please close attention to that.
appService
.httpCall({
url: "/posts",
params: {
posts: $scope.data.postbuzz,
from_user_id: $scope.data.username,
},
})
.then((response) => {
$scope.$apply();
})
.catch((error) => {
alert(error.message);
});
make sure that the data that you calling from this above function is similar to $scope parameter you passing in your route file that your requesting:
const data = {
posts : request.body.posts,
from_user_id: request.body.from_user_id}
and in your database helper class you running:
`INSERT INTO posts (from_user_id,post) values (?,?)`,
[params.from_user_id,params.posts]
Hope this was helpful
You seem to have an understand already. your question may help a lot more people in the future.
params should be as following, since the data object has properties from_user_id and posts
`INSERT INTO posts (from_user_id,posts) values (?, ?)`,
[params.from_user_id,params.posts]
Might be useful https://www.w3schools.com/nodejs/nodejs_mysql_insert.asp
--- EDIT 2 ---
After closely looking at the code and fixing some naming variables the code works fine, the data is being inserted in mysql as it should.
If you are new to Angular you can use the code as reference.
I am currently stuck with this project : integrating GA to my REST API so I can retrieve metrics and dimensions.
I must highlight that I am running the API on localhost, it may explain why it does not work...?
I tried to integrate GA following different ways :
1. Using universal-analytics (https://github.com/peaksandpies/universal-analytics/blob/master/AcceptableParams.md)
const ua = require('universal-analytics');
require('dotenv').config({path: '../.env'});
// to retrieve the number of connexions to the homepage
server.route({
method: 'GET',
path: '/homepage',
handler: function (request, reply) {
...
const visitor = ua(process.env.UA_ID);
visitor.pageview('/bookmarks', 'http://localhost:4000', 'Homepage', (err) => {
if (err) {
throw err;
}
});
return reply.view('index');
}
});
// I have pretty much the same thing at the end of a POST endpoint handler
// to retrieve the number of new data posted
handler: function (request, reply) {
...
const user = ua(process.env.UA_ID, userId(request.auth.credentials.username));
user.event('Bookmarks', 'new_bkm_created', payload.title, (err) => {
if (err) {
throw err;
}
});
}
2. Creating a trackEvent function (https://cloud.google.com/appengine/docs/flexible/nodejs/integrating-with-analytics)
in google.js
const got = require('got');
module.exports = function trackEvent (propertyId, category, action, options) {
const data = {
v: '1', // API version
tid: propertyId, // Tracking / Property ID.
t: 'event', // Event hit type.
ec: category, // Event category.
ea: action // Event action.
};
if (options) {
if (options.label) {
data.el = options.label; // Event label.
}
if (options.value) {
data.ev = options.value; // Event value.
}
}
return got.post('http://www.google-analytics.com/collect', {
body: data,
form: true
});
};
in app.js
require('dotenv').config({path: '../.env'});
const trackEvent = require('./google');
const postHandler = (request, reply) => {
...
trackEvent(process.env.UA_ID, 'Thing', 'new_thing_created').then(() => {
return reply(bookmark).code(201);
}
}
3. Pasting the website tracking code from Admin --> Property ---> Tracking Info (https://developers.google.com/analytics/devguides/collection/analyticsjs/)
<script>
(function(i,s,o,g,r,a,m)i['GoogleAnalyticsObject']=ri[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;.parentNode.insertBefore(a,m)})(window,document,'script','https://www.google-analytics.com, 'analytics.js','ga');
ga('create', 'UA-XXX-whatev', 'auto');
ga('send', 'pageview');
</script>
I also tried the async version proposed on the link on the third title. The thing is, I do not like this way of doingm I do not understand how to launch events and page views from handlers with ga created in the front end...
Anyway, none of them works... I have no error, but nothing appears in G Analytics.
Just so you know, I used example.com in the default URL as it does not work with a localhost url.
Do you have any lead to help me with this?
Thank you so much in advance!
-- smgr
Turned out one of the three methods worked: the first one with universal-analytics. One needs to be patient to see the first tracked events. I warmly recommend this module though, very developer-friendly ;)
I am trying to use the cordova social sharing plugin for sharing video on social sites. So far what I have achieved is, I have successfully captured video using following code -
var options = {
limit: 1,
duration: 15
};
$cordovaCapture.captureVideo(options).then(function (videoData) {
$scope.videoUrl = videoData[0].fullPath;
}, function (err) {
// An error occurred. Show a message to the user
//alert("video error : "+err);
});
I can successfully find the captured video files url but unfortunately I can not share them to the social media sites. I have tried both of the following methods -
$cordovaSocialSharing
.share(message, subject, file, link)
and
$cordovaSocialSharing
.shareViaTwitter(message, image, link)
Now my question is -
Is there any way to share video through this approach?
If not, please let me know if there is any possible way for this.
N.B. : I have already bothered the Google a lot.
Thanks in advance.
my problem was passing a bad filePath, so i found a solution like below :
import {CaptureError, MediaFile, MediaCapture, CaptureImageOptions, Transfer} from "ionic-native";`
declare let cordova: any;
private static options = {
message: '', // not supported on some apps (Facebook, Instagram)
subject: '', // for email
files: [''], // an array of filenames either locally or remotely
url: ''
};
videoOptions: CaptureImageOptions = {limit: 1};
videoData: any;
captureVideo() {
MediaCapture.captureVideo(this.videoOptions)
.then(
(data: MediaFile[]) => {
this.videoData = data[0];
const fileTransfer = new Transfer();
fileTransfer.download(this.videoData.fullPath, cordova.file.applicationStorageDirectory + 'fileDir/filename.mp4').then((entry) => {
this.options.message = " Your message";
this.options.subject = "Your Subject";
this.options.files = [entry.toURL()];
this.options.url = "https://www.google.com.tr/";
SocialSharing.shareWithOptions(this.options);
}, (error) => {
});
},
(err: CaptureError) => {
}
);
}
As you see above, i just copy my video file to applicationStorageDirectory
I've just started to have a play with meteor and I'm slowly moving a
NodeJS/Express app over to meteor. However on my blog section, I can't seem to get a single post _id into the helper. With NodeJS alone, I could use req.params._id.
Using the Differential boilerplate as a starting poing, (still using insecure and autopublish in dev) I have this:
//both/controllers/post.js
PostController = AppController.extend({
waitOn: function() {
return this.subscribe('posts');
},
data: function () {
return Posts.findOne({_id:this.params._id});
}
});
And in the router file
//both/router/router.js
Router.route('/posts/:_id', {
name: 'post'
});
The links on the main blog listing page, to the single posts are formated as follows.
//client/templates/blog/blog.html
<h3>{{ title }}</h3>
Then the helper file which seems to be the issue?
// /client/templates/post/post.js
Template.post.rendered = function() {
};
Template.post.helpers({
data: function () {
return Posts.findOne({_id:this.params._id});
}
});
Template.post.helpers({
createdAtFormatted: function () {
return moment(this.createdAt).fromNow();
}
});
I've tried this.params._id, request.params.id, req.params._id,
And other than setting an on click event and setting the _id in session (I don't like this idea, if it will even work efficiently/effectively). I'm stuck on ideas.
I've inherited a Cordova/PhoneGap app running Cordova 3.4. My first task was to implement a Client-Side Routing framework to make it easier to navigate between pages. I chose Flatiron Director as my client-side router, but when I went to implement it I started to get weird functionality out of the app.
My first router setup:
var routing = {
testHandler: function(){
console.log('Route ran');
},
routes: function(){
return {
"/testhandler": testHandler
}
}
};
console.log('Routes added');
The routes are added (at least based on the console output). When I attempt to hit the /testhandler hash, I receive a "Failed to load resource: file:///testhandler" error when I set window.location.hash to "/testhandler". I noticed the "Route ran" statement was never printed.
My next attempt was just using the hashchange event with jQuery.
$(window).on('hashchange', function(){ console.log('Ran'); });
On this attempt, regardless of what I change the hash to, I see the 'Ran' output, but I still receive the "Failed to load resource: " error.
Is this a problem with PhoneGap/Cordova? Or our implementation? Is it just not possible to use client-side routing with Cordova? What am I doing wrong?
I know that this doesn't answer your question directly but you may consider making your own provisional router. This may help you to debug your app and to figure out what's the problem.
Something like this for example:
var router = (function (routes) {
var onRouteChange = function () {
// removes hash from the route
var route = location.hash.slice(1);
if (route in routes) {
routes[route]();
} else {
console.log('Route not defined');
}
};
window.addEventListener('hashchange', onRouteChange, false);
return {
addRoute: function (hashRoute, callback) {
routes[hashRoute] = callback;
},
removeRoute: function (hashRoute) {
delete routes[hashRoute];
}
};
})({
route1: function () {
console.log('Route 1');
document.getElementById('view').innerHTML = '<div><h1>Route 1</h1><p>Para 1</p><p>Para 2</p></div>';
},
route2: function () {
console.log('Route 2');
document.getElementById('view').innerHTML = '<div><h1>Route 1</h1><p>Para 1</p><p>Para 2</p></div>';
}
});