Pybossa JS - taskLoaded() function executes twice when fetching 1 task - javascript

I am currently building a custom task presenter for my PYBOSSA project. I have almost implemented it, but am stuck at the following javascript function -
pybossa.taskLoaded(function(task, deferred) {
if ( !$.isEmptyObject(task) ) {
console.log("Hello from taskLoaded");
// load image from flickr
var img = $('<img />');
img.load(function() {
// continue as soon as the image is loaded
deferred.resolve(task);
pybossaNotify("", false, "loading");
});
img.attr('src', task.info.url).css('height', 460);
img.addClass('img-thumbnail');
task.info.image = img;
console.log("Task ##"+task.id);
}
else {
deferred.resolve(task);
}
});
According to the docs -
The pybossa.taskLoaded method will be in charge of adding new items to the JSON task object and resolve the deferred object once the data has been loaded (i.e. when an image has been downloaded), so another task for the current user can be pre-loaded.
But notice my function. I have logged the task ids, the function loads. It loads 2 tasks. After logging, the console shows -
Task ##256
Task ##257
Also I have tried various other statements. They also execute twice. What I think is that if now I try to insert question of the current task, the function of the next task will also be put along with its respective image. How do I resolve this?

You are seeing double for a good reason :-) PYBOSSA preloads the next task, so the final user does thinks that the next task loads really fast (actually instantly).
While for some projects this might not be a problem, in some cases the user needs to download big images, check other APIs, etc. so it takes 2 or 3 seconds (or even more) to get everything before presenting the task to the user.
PYBOSSA.JS handles this scenario, as soon as the data has been downloaded, it requests a new task, but instead of presenting it, you have it in your window. As you are building your own template, you will have to add that data into the dom (via hidden elements) and then in the pybossa.presentTask method, you will check which task is being loaded, and show/hide the previous one.
In pybossa.saveTask, you can delete the previous DOM elements.
I hope this is now more clear. If you don't want this, you can use jQuery or Axios to request a task, save it and load the next one when you want ;-)

Related

How to change page size Margins and document language through Word Api ? is any alternate way to do that?

i tried to find word api for that but i guess that is not available
right now so i thought i can do it by modifying the xml but that
also didn't work, need to change page size margin and document
language
await Word.run(async (context) => {
var paragraphs = context.document.body;
// Queue a command to load the style property for the top 2 paragraphs.
paragraphs.load("style")
// Synchronize the document state by executing the queued commands,
// and return a promise to indicate task completion.
return context.sync().then(function () {
// let replacedXml=""
// Queue a a set of commands to get the OOXML of the first paragraph.
var ooxml = paragraphs.getOoxml()
// Synchronize the document state by executing the queued commands,
// and return a promise to indicate task completion.
return context.sync().then(function () {
// console.log('Paragraph OOXML: ' + ooxml.value);
console.log(ooxml.value)
let str=String(ooxml.value)
let replacedXml =ooxml.value
// paragraphs.items[0].insertOoxml(replacedXml,Word.InsertLocation.replace)
// context.document.body.insertOoxml(replacedXml, Word.InsertLocation.replace);
var range = context.document.getSelection()
range.insertOoxml(replacedXml,"Replace")
// console.log(replacedXml)
});
});
i tried to find word api for that but i guess that is not available right now
The answer is yes. Here is no such api having functionality as your expectation for now and in recent future.
so i thought i can do it by modifying the xml but that also didn't work, need to change page size margin and document
OOxml is a powerful way to change doc file indeed, but it is only applicable for those very experienced, has a bit unsatisfying performance online and may cause some problems hard to interpret. So in most cases, we don't recommend using ooxml to achieve one's goal actually.
Btw, we suggest to test above code in word desktop app. Only if insuring the correctness of code could support us to go on investigating.
At last, you can submit your request in https://techcommunity.microsoft.com/t5/microsoft-365-developer-platform/idb-p/Microsoft365DeveloperPlatform if you really want new api.

Call function without actually executing it

So I have such a weird question and I don't know if this is possible, but I will give it a shot anyways.
We have implemented OneTrust, which is a third-party cookie consent vendor and it works great and all, but we have one small hiccup that we are trying to resolve.
So within the below function:
toggleVideo: function (videoWrapper, src, cover, type, element) {
var videoElement = video.buildVideo(src, type);
// We build out video-player element
videoWrapper.html(videoElement);
// We define our variables
let onetrust = window.OneTrust;
let onetrust_obj = window.ONETRUST_MODULE;
let target = videoWrapper.html(videoElement).children('iframe');
console.log(onetrust.Close());
// Now we wait and observe for a src attribute and then show the video.
onetrust_obj.src_observer(target, function() {
video.toggle_show(videoWrapper, cover);
});
},
We have an <iframe> element that when clicked play, will wait for consent to execute - The problem is that it needs to "refresh" OneTrust so that it can change the data-src to src attribute (This is all handled using OneTrust JS, so I have no control).
When I add in the console.log(onetrust.Close());, it works just as intended and resumes playing the video when consent is given, the downfall is that it outputs an error in the console. If I remove it, the videos will not play after consent is given.
I don't want to actually execute the onetrust.Close() method as it will close the banner.
OneTrust doesn't have a proper way to "Refresh" their initialization, the techs told me that this was a one-off case, where they don't even know how to handle it.
My questions:
Is there a way that I can properly call onetrust.Close() (Seems to be the only call that actually engages the video to play after) without actually executing it?
If not, is there a way that I can somehow similarly log it, but not actually log it in the console?
Thanks all!
Strange one, may be a race-condition issue so making your code run in the next procedural iteration may resolve the issue - this can be done by adding a setTimeout with no timer value.
setTimeout(() => {
onetrust_obj.src_observer(target, function() {
video.toggle_show(videoWrapper, cover);
});
});
Alternatively, it may be worth digging into the onetrust.Close() method to see if there are any public utilities that may help 'refresh' the context you are working in.
Another idea would be to see what happens after if you ran the onetrust_obj.src_observer code block again.
EDIT: I would like to be clear that I'm just trying to help resolve debugging this, without seeing a working environment it's difficult to offer suggestions 😄

Timing React.js Application

I am working with a 3rd party APM tool which provides a javascript agent to give insight into the visibility of UI rendering times.
Understanding that that React.js doesn't really map well to the browser timings API, can anyone shed any insight into when I would measure the below metrics? I included the available API calls that the vendor provides.
Metrics to report
End User Response Time - virtualPageStart() to virtualPageEnd()
HTML Download Time - viewChangeStart() to viewChangeEnd()
HTML Download & DOM Building Time - viewChangeStart() to viewDOMLoaded()
DOM Building Time - viewChangeEnd() to viewDOMLoaded()
DOM Ready Time - viewChangeStart to viewDOMLoaded
Available API Calls
markViewChangeStart() Sets the view change start time.
markViewChangeEnd() Sets the view change end time.
markViewDOMLoaded() Sets the view DOM loaded time.
markXhrRequestsCompleted() Sets the XHR requests completed time.
markViewResourcesLoaded() Sets the view resources loaded time.
markVirtualPageStart() Sets the virtual page start time.
markVirtualPageEnd() Sets the virtual page end time.
THANKS!!!
For most of these items, you are actually not affected by React itself. You can record the changestart/changeend events with your routing library. If you don't use any routing library, your pseudocode would look like this:
markViewChangeStart();
ReactROM.render(component, domNode, function() {
markViewChangeEnd();
});
For DOM loaded, you can use the first time markViewChangeEnd is called:
markViewChangeStart();
ReactROM.render(component, domNode, function() {
if (!window.rendered) {
markViewDOMLoaded();
window.rendered = true;
}
markViewChangeEnd();
});
For the RequestsComplete event, you can hold a global variable to mark you have started making requests, an when all of your requests are resolved, call the RequestsCompleted() event.
I think page start and end events can be called at the same place with changeend and change start.
For the ResourcesLoaded, I'm not sure how it could be handled.

Phaser: how to load assets after preload?

I wonder whether it would be possible to load an asset dynamically at a given time in Phaser rather than loading everything in the preload function. The reason for this is simple: I have a game with three different levels, all of which have different background songs; and so I'd rather only load a single song at startup to reduce loading times.
Right now, my preload function looks like this:
preload: function()
{
game.load.audio('pixel_world',
['assets/music/pixel_world_lo.ogg', 'assets/music/pixel_world_lo.mp3']);
game.load.audio('second_source',
['assets/music/second_source_lo.ogg', 'assets/music/second_source_lo.mp3']);
game.load.audio('reboot_complete',
['assets/music/reboot_complete_lo.ogg', 'assets/music/reboot_complete_lo.mp3']);
game.load.image('pickup', 'assets/img/pickup.png');
}
I tried moving one of the game.load.audio() calls to the create function instead:
create: function()
{
game.load.audio('pixel_world',
['assets/music/pixel_world_lo.ogg', 'assets/music/pixel_world_lo.mp3']);
// good things follow...
}
However, the following calls fail:
this.cache.isSoundDecoded(level.song)
// Phaser.Cache.isSoundDecoded: Key "pixel_world" not found in Cache.
song = game.add.audio(level.song);
// Phaser.Cache.getSound: Key "pixel_world" not found in Cache.
Do you know how I can get this to work, or any other way to ensure that the three songs are not loaded at game startup? Thank you!
From the documentation, that big unknown for noobs like me:
audio(key, urls, autoDecode) → {Phaser.Loader}
Adds an audio file to the current load queue.
The file is not loaded immediately after calling this method. The file is added to the queue ready to be loaded when the loader starts.
So basically, game.load.audio() after preload isn't loading the song, just adding it to a queue for later. In order to load the song, I also need to invoke game.load.start():
create: function()
{
game.load.audio('pixel_world',
['assets/music/pixel_world_lo.ogg', 'assets/music/pixel_world_lo.mp3']);
game.load.start(); // THIS!
// good things follow...
}

PyBossa loading and presenting tasks

I am trying to set up a project on CrowdCrafting.org by using the PyBOSSA framework.
I followed their tutorial for project development.
The first parts seemed very clear to me, creating the project and adding the tasks worked fine.
Then I built my own HTML webpage to present the task to the users. Now the next step would be to load the tasks from the project, present them to the users, and save their answers.
Unfortunately, I don't understand how to do this.
I will try to formulate some questions to make you understand my problem:
How can I try this out? The only way seems to be by updating the code and then running pbs update_project
Where can I find documentation for PyBossa.js? I just saw (in the tutorial and on other pages) that there are some functions like pybossa.taskLoaded(function(task, deferred){}); and pybossa.presentTask(function(task, deferred){});. But I don't know how they work and what else there is. This page looks like it would contain some documentation, but it doesn't (broken links or empty index).
How do I use the library? I want to a) load a task, b) present it to the user, c) show the user his progress, and, d) send the answer. So I think I'll have to call 4 different functions. But I don't know how.
Looking at the example project's code, I don't understand what this stuff about loading disqus is. I think disqus is a forum software, but I am not sure about that and I don't know what this has to do with my project (or theirs).
As far as I understand, the essential parts of the JS-library are:
pybossa.taskLoaded(function(task, deferred) {
if ( !$.isEmptyObject(task) ) {
deferred.resolve(task);
}
else {
deferred.resolve(task);
}
});
pybossa.presentTask(function(task, deferred) {
if ( !$.isEmptyObject(task) ) {
// choose a container within your html to load the data into (depends on your layout and on the way you created the tasks)
$("#someID").html(task.info.someName);
// by clickin "next_button" save answer and load next task
$("#next_button").click( function () {
// save answer into variable here
var answer = $("#someOtherID").val();
if (typeof answer != 'undefined') {
pybossa.saveTask(task.id, answer).done(function() {
deferred.resolve();
});
}
});
}
else {
$("#someID").html("There are no more tasks to complete. Thanks for participating in ... ");
}
});
pybossa.run('<short name>');
I will try to answer your points one by one:
You can either run pbs update project or go to the project page >
tasks > task presenter and edit the code there.
I believe this link works, and there you should find the
information you want.
So, once you've created the project and added the tasks and the
presenter (the HTML you've built) you should include the Javascript
code inside the presenter itself. You actually only need to write
those two functions: pybossa.taskLoaded(function(task,
deferred){}); and pybossa.presentTask(function(task, deferred){});
Within the first one you'll have to write what you want to happen
once the task has been loaded but before you're ready to present it
to the user (e.g. load additional data associated to the tasks,
other than the task itself, like images from external sites). Once
this is done, you must call deferred.resolve(), which is the way
to tell pybossa.js that we are done with the load of the task
(either if it has been successful or some error has happened).
After that, you must write the callback for the second one
(pybossa.presentTask) where you set up everything for your task,
like the event handlers for the button answer submission and here is
where you should put the logic of the user completing the task
itself, and where you should then call pybossa.saveTask(). Again,
you should in the end call deferred.resolve() to tell pybossa.js
that the user is done with this task and present the next one. I
would recommend you to do in inside the callback for
pybossa.saveTask(task).done(callbackFunc()), so you make sure you
go on to the next task once the current one has correctly been
saved.
You can forget about that discuss code. These are only templates
provided, in which there is included some code to allow people
comment about the tasks. For that, Disquss is used, but it is up to
you whether you want to use it or not, so you can safely remove this
code.

Categories

Resources