In rails I've built a sort of cronjob, but once the view is rendered there some code I would like to run like a 'signoff' on the task processed.
Where would I put code so that it is run at the absolute end of processing (once the view is rendered)
How does rails process html does it buffer? (Would it flush HTML to the user as its rendered or once its rendered?)
You can render the view to a string, catch any Timeouts that could happen while rendering, log the results of the action, and return the string:
begin
#elements = Element.find(:all)
html = render_to_string
# Store the result
Result.create(:element_count => #elements.count)
rescue Timeout::Error
# Store the result of the call as failed?
Result.create(:element_count => 0)
end
send_data html, :disposition => 'inline', :type => 'text/html'
Some other things that you can do to achieve your goal could be:
You can use a rake task instead of a controller action, if the code that you need to execute is only triggered by your cron job.
Instead of directly making a request using wget in your cron job, you can call a script that will make a request to your controller, inspect the output of the request, and then log the result (maybe by calling a new action in the controller).
To pick an element from the rendered HTML, you could read the value using javascript/JQuery:
$(document).ready(function() {
var completion = $('#items_processed').val();
});
Related
I have a problem for writing tests for conditional cases. One of the test uses the api in 'before' (beforeAll) function to create an object, and then in test the object that was created is not shown in searching result sometimes. I was using puppeteer before. I can let the page reload until the object shows in the search result. However, there is no way for me to do the same thing. I was thinking of using cy.get and then checking the response. For instance, (cy.get('sth').then(s1 => {do something like cy.reload()})).
Then, I found out that s1 always kept the same after reload. So, I am stuck. Hope someone give me a hand to it. If the description is not clear, please the my another post below. Thanks
Im sorry but the problem is in your before function. You gotta start it only when you are done preparing your environments to run your test.
const createPerson = (params, done)=>{
cy.request({// create people here}).then(({people})=>{
done(undefined, {people});
})
}
before((done)=> {
createPerson({}, (err, {people})=>{
cy.visit('mywebsite);
login({}, done); // this should be async as well
});
})
it('search person I created by calling api', () => {
//if you data is not cached, at this point you will have the people populated in your screen.
cy.get('.search')
.type('person's name{enter}');
cy.get(':nth-child(1) > resulttable').click();
Based on what I'm gathering from your post, I think something like this may help:
cy.get('some.selector').then(elem => {
// ...
});
cy.reload();
cy.get('some.selector').then(elem => {
// run code on element after reloading...
});
If this does not answer your question, please consider making a minimal, complete and verifiable example.
My bad. I didn't explain my problem well. The problem is not in before() function. In before() function, I call post API to create persons.
Then, I will use those persons created in before() function in each of my tests.
The code would look like:
before(()=> {createPerson(); cy.visit('mywebsite); login();} )
it('search person I created by calling api', () => {
cy.get('.search')
.type('person's name{enter}');
cy.get(':nth-child(1) > resulttable').click();
Here is the problem. I can't find the person in search result since the data needs time to be passed. Then, the test fails.
So, I need reload the page (The page is searching result page) by calling
cy.reload();
However, I don't know how many reload I need to call above to let the person show up in the searching result.
The current solution I used is to cy.wait(30000). wait 30 seconds.
So, I am wondering how I am going to do right now.
In my dashboard I have a job where I would like to get a value from my widget.
# :first_in sets how long it takes before the job is first run. In this case, it is run immediately
SCHEDULER.every '1s', :first_in => 0 do |job|
send_event('my_widget', { value: rand(400) })
end
This is the code to send data to my widget, but how could I get the data? What is the "get_event" that I'm looking for?
From this issue in dashing github repository, You can use server sent events to get data from dashing dashboard.
Dashing provides data from the same API end point
http://dashingdemo.herokuapp.com/events
Excerpt from returned data
data: {"current":77,"last":82,"id":"valuation","updatedAt":1461840437}
data: {"current":104578,"last":89199,"id":"karma","updatedAt":1461840437}
data: {"value":62,"id":"synergy","updatedAt":1461840437}
I have built a MVCPortlet that runs on Liferay 6.2.
It uses a PortletPReferences page that works fine to set/get String preferences parameters via the top right configuration menu.
Now I would need to store there a String[] instead of a regular String.
It seems to be possible as you can store and get some String[] via
portletPreferences.getValues("paramName", StringArrayData);
I want the data to be stored from a form multiline select.
I suppose that I need to call my derived controller (derived from DefaultConfigurationAction) and invoke there portletPreferences.setValues(String, String[]);
If so, in the middle, I will neeed the config jsp to pass the String[] array to the controller via a
request.setAttribute(String, String[]);
Do you think the app can work this way in theory?
If so, here are the problems I encountered when trying to make it work:
For any reason, in my config jsp,
request.setAttribute("paramName", myStringArray);
does not work ->
actionRequest.getAttribute("paramName")
retrieves null in my controller
This is quite a surprise as this usually works.
Maybe the config.jsp works a bit differently than standard jsps?
Then, how can I turn my multiline html select into a String[] attribute?
I had in mind to call a JS function when the form is submitted.
this JS function would generate the StringArray from the select ID (easy)
and then would call the actionURL (more complicated).
Is it possible?
thx in advance.
In your render phase (e.g. in config.jsp) you can't change the state of your portlet - e.g. I wouldn't expect any attributes to persist that are set there. They might survive to the end of the render phase, but not persist to the next action call. From a rendered UI to action they need to be part of a form, not request attributes.
You can store portletpreferences as String[], no problem, see the API for getting and setting them
I think maybe you can use an array in client side, and you can update the javascript array, when user is selecting new values.
So you have the javascript array, then when user click on the action, you can execute the action from javascript also, something like this:
Here "products" is the array with your products.
A.io.request(url, {type: 'POST',
data: {
key: products
},
on: {
success: function(event, id, obj) {
}
}
});
From Action methd you can try to get the parameter with:
ParamUtil.getParameterValues(request,"key");
How can I use Prawn to generate PDF of form data in Sinatra?
My form is at the index action of the site but Prawn doesn't recognize the variables passed in. I've found this code in the documentation at http://prawnpdf.org/docs/0.11.1/Prawn/Document.html.
get '/download' do
content = "Hello World"
Prawn::Document.generate "example.pdf" do |pdf|
pdf.font "Times-Roman"
pdf.draw_text content, :at => [200,720], :size => 32
end
end
Now this is great, but when I try to pass in my variables from the parameters like this:
post '/resume' do
#name = params.fetch 'name'
...
end
And then if I add that into the /download route like this:
get '/download' do
Prawn::Document.generate "example.pdf" do |pdf|
pdf.font "Times-Roman"
pdf.draw_text #name, :at => [200,720], :size => 32
end
end
It it will draw nothing. Also, weirdly, it generates a pdf file but doesn't redirect to it and I have to manually load it.
Really stuck on this one - advice?
Every request creates a new instance of your Sinatra app to serve it. Therefore, instance variables won't be the same across 2 different requests. You either need to persist the data using one of the many ways to do this (cookies, local storage, database, cache etc) or you need to put the Prawn logic in the POST route.
so I'm trying to make a call to a bible verse API in my Meteor application. I made a template with name="display", with a simple {{checkitout}} in the template.
Then for the template, I tried to make the call in its corresponding helper. It looks like this (in coffeescript, but Javascript readers should understand as well):
#Template.display.helpers
checkitout:->
result = Meteor.http.call("GET","http://labs.bible.org/api/passage=john%203:2&type=json")
console.log(result)
The URL is a JSON of a bible verse, but the problem is, the Meteor.http.call requires a third argument, a "callback" (because this is in the client folder). I read some documentation + examples and have no idea what it means.
Also, if I call it like this, is result exactly the JSON file, or do I need to fit it within a new hash? And what does a callback mean? Can someone give me an example?
As helpers are synchronous and API calls are not, you need to store the call result in a reactive variable and return it from the helper:
verse = "Loading..."
verseLoaded = false
verseDep = new Deps.Dependency()
Template.Display.checkItOut = ->
verseDep.depend()
unless verseLoaded
verseLoaded = true
Meteor.http.get "...", (error, result) ->
verse = "..."
verseDep.changed()
verse
On the client, the callback is required as you said. So this is something you could do to query an API and display the JSON result:
Template.Display.helpers
checkItOut: ->
Meteor.http.get 'https://graph.facebook.com/facebook', (error, result) ->
if not error
console.log result # display the the open graph result
Note 1: To use these functions, you need to add the HTTP package to your project with $ meteor add http. You can find further information in the documentation.
Note 2: In your situation, you cannot make an API call client-side due to the Access-Control-Allow-Origin Policy. So, the solution would be to use a method and make the call server-side.
# Client-side
Template.Display.helpers
checkItOut: ->
Meteor.call 'getBibleText', (error, result) ->
if not error
console.log result
# Server-side (server directory)
Meteor.methods
'getBibleText': ->
result = HTTP.get 'http://labs.bible.org/api/?passage=john%203:2&type=xml'
return result