JQuery not getting included in PhantomJs - javascript

I am trying to use jquery with phantomjs. I tried a standalone example and it worked fine. Here is what I did:
var page = require('webpage').create();
page.open("http://www.phantomjs.org", function(status) {
page.onConsoleMessage = function(msg) {
console.log("message recvd: " + msg);
};
var result;
page.includeJs("https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js", function() {
console.log("loading jquery");
});
setTimeout(function() {
page.evaluate(function() {
console.log("$(\"title\").text() -> " + $("title").text());
});
}, 1000);
}
Here is the output I got:
loading jquery
message recvd: $("title").text() -> PhantomJS | PhantomJS
In the above code snippet, I have used setTimeout() on evaluate function because includeJs() would execute asynchronously and need some time to load jquery. If I do not use setTimeout() or use a small value for timeout, it doesn't work.
However, when I try the same code in my application it doesn't work. Here is what I have:
var baseSetup = function(guid, page, config, request, response) {
/* enable the console output inside the callback functions */
page.onConsoleMessage = function (msg) {
console.log(guid + ": console msg: " + msg);
};
/* used for ignoring potential alert messages when evaluating js code */
page.onAlert = function (msg) {
console.log(guid + " (alert): alert msg: " + msg);
};
/* suppress the error messages */
page.onError = function(msg, trace) {
var msgStack = ['ERROR: ' + msg];
if (trace && trace.length) {
msgStack.push('TRACE:');
trace.forEach(function(t) {
msgStack.push(' -> ' +
t.file +
': ' +
t.line +
(t.function ? ' (in function "' + t.function + '")' : ''));
});
}
console.error(guid + ": " + msgStack.join('\n'));
};
}
module.exports = function extractionDriver(responseFromUrl, responseToUser, page, request) {
console.log(page.customHeaders['guid'] + ": extractionDriver, status = " + responseFromUrl.status);
if(page.isLocalFile || responseFromUrl.status !== 0)
{
var viewportStr = page.customHeaders['viewportStr'];
console.log(page.customHeaders['guid'] + ": Setting viewport size: " + viewportStr);
var viewportObj = parseViewport(viewportStr);
page.viewport = viewportObj;
page.evaluate(function(w,h) {
document.body.style.width = w + "px";
document.body.style.height = h + "px";
}, viewportObj.width, viewportObj.height);
page.includeJs("https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js", function() {
console.log("loading jquery");
});
setTimeout(function() {
page.evaluate(function() {
console.log("$(\"title\").text() -> " + $("title").text());
});
}, 1000);
}
And this is what I see when I run my application:
d8db6045-a0e8-11e4-a619-6949593d958d: ERROR: ReferenceError: Can't find variable: $
TRACE:
-> phantomjs://webpage.evaluate(): 3
-> phantomjs://webpage.evaluate(): 4
-> phantomjs://webpage.evaluate(): 4
The log line "loading jquery" is never printed and jquery is never loaded.
I have tried wrapping up the evaluate() function inside the callback of includeJs() but that didn't work either (no console log printed).
What could be going wrong here? Please let me know if I should provide more information.

That is why page.includeJs has a callback, so you can put the code that depends on jQuery in there. The callback is called when the referenced JavaScript is already loaded. Welcome to another level on the road to the callback hell.
I experienced one time though that this didn't work for some reason. The workaround was to set a global variable in the includeJs callback and use waitFor to wait for the global variable to be set outside of the includeJs callback.
var _loadIndicator = false;
page.includeJs("https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js", function() {
_loadIndicator = true;
});
waitFor(function check() {
return _loadIndicator;
}, function onReady() {
page.evaluate(function() {
console.log("$(\"title\").text() -> " + $("title").text());
});
}, 10000);

I just have troubles with this, but my mistake was that, i tried phantom.injectJs, not page.injectJs (jerk). And then, if status is success, put
page.injectJs('lib/jquery.min.js');
and try
page.evaluate(function(){
console.log($("body").length);
});

Related

Office.js outlook add-in issue

I'm trying to get the Body in Outlook and then update/set it with categories. My issue is this - when I debug it - it works fine. But when I don't debug from function to function - it gets all the way to the last function and just stops - updateBody(). What's really strang is if I remove the breakpoints on each function and just set a breakpoint on last function - never gets hit, but console will write out "Starting update body". All the console.logs are writing out data as expected. Not sure what is going on. Appreciate any help! Thanks.
"use strict";
var item;
var response;
var tags;
var updatedBody;
Office.initialize = function () {
$(document).ready(function () {
// The document is ready
item = Office.context.mailbox.item;
debugger;
getBodyType();
});
}
function getBodyType() {
item.body.getTypeAsync(
function (resultBody) {
if (resultBody.status == Office.AsyncResultStatus.Failed) {
write(resultBody.error.message);
} else {
response = resultBody;
console.log('Successfully got BodyType');
console.log(response.value);
getCategories();
}
});
}
function getCategories() {
tags = "";
// Successfully got the type of item body.
// Set data of the appropriate type in body.
item.categories.getAsync(function (asyncResult) {
if (asyncResult.status === Office.AsyncResultStatus.Failed) {
console.log("Action failed with error: " + asyncResult.error.message);
} else {
var categories = asyncResult.value;
console.log("Categories:");
categories.forEach(function (item) {
var tag = item.displayName;
tags += '#' + tag.replace(/\s/g, "") + ' ';
});
console.log('Successfully got tags');
console.log(tags);
getBody();
}
});
}
function getBody() {
var body = "";
updatedBody = "";
console.log("Starting get body");
if (response.value == Office.MailboxEnums.BodyType.Html) {
item.body.getAsync(
Office.CoercionType.Html,
{ asyncContext: "This is passed to the callback" },
function (result) {
//Replace all the # tags and update again.
body = result.value.replaceAll(/#(\w)+/g, "").trimEnd();
var domParser = new DOMParser();
var parsedHtml = domParser.parseFromString(body, "text/html");
$("body", parsedHtml).append("<div>" + tags + "</div>");
var changedString = (new XMLSerializer()).serializeToString(parsedHtml);
if (changedString != "") {
updatedBody = changedString;
}
console.log(updatedBody);
updateBody();
});
}
}
function updateBody() {
console.log("Starting update body");
item.body.setAsync(
updatedBody,
{ coercionType: Office.CoercionType.Html },
function (result2) {
console.log("Body updated");
});
}
Image - With breakpoints on each function - works as expected
Image - Without breakpoints - gets to updateBody() function.
But the string updatedBody isn't logged. It somehow skips over that
even though it's called before updateBody() on getBody()
Image - Same code run via Script Lab - works just fine as well.

ActionCable too fast for DOM update

I have a situation where I am updating a the DOM with information from a 3rd party website at the same time that I am creating an object on the backend with ajax. Sometimes the ajax call returns slower than the separate job responds through ActionCable.
On the front-end I'm rendering the 3rd party results but when the DOM hasn't been updated I end up with an un-updatable DOM. Is there another way to handle a delay other than just with a setTimeout? Because if for some reason I don't wait long enough, the DOM update will still fail.
EDIT: Code of what I'm trying to do.
connectPosts: function connectPosts(){
var self = this;
if (!webSockets) { return }
App.cable.subscriptions.create({
channel_id: channel_id,
channel: 'PostsChannel'
},{
received: function(data){
var $element = $('#' + data['object_type'] + '_' + data['object_id'] + ' .container');
if($element.length == 0)
setTimeout(function(data){self.buildElement(data)}, 1000, data);
else
self.buildElement(data);
}
});
},
buildElement: function buildElement(data){
var $element = $('#' + data['object_type'] + '_' + data['object_id'] + ' .container');
var content = HandlebarsTemplates['posts/element'](data);
$element.html(content);
if($element.find('.author-' + self.currentUser.id)){
$element.find('a').show();
}
}
};

Phonegap barcode scanner: couldn't make it run

I've tried to create a default Phonegap barcode scanner trough plugin basic installation, but it didn't work well. I don't know what's happening. Here is my code:
var app = {
// Application Constructor
initialize: function() {
this.bindEvents();
},
// Bind Event Listeners
// Bind any events that are required on startup. Common events are:
// 'load', 'deviceready', 'offline', and 'online'.
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
// deviceready Event Handler
// The scope of 'this' is the event. In order to call the 'receivedEvent'
// function, we must explicitly call 'app.receivedEvent(...);'
onDeviceReady: function() {
app.receivedEvent('deviceready');
},
// Update DOM on a Received Event
receivedEvent: function(id) {
var parentElement = document.getElementById(id);
var listeningElement = parentElement.querySelector('.listening');
var receivedElement = parentElement.querySelector('.received');
listeningElement.setAttribute('style', 'display:none;');
receivedElement.setAttribute('style', 'display:block;');
console.log('Received Event: ' + id);
console.log('-');
console.log(cordova);
console.log('-');
console.log(cordova.plugins.barcodeScanner);
console.log('-');
cordova.plugins.barcodeScanner.scan(
function (result) {
alert("We got a barcode\n" +
"Result: " + result.text + "\n" +
"Format: " + result.format + "\n" +
Cancelled: " + result.cancelled);
},
function (error) {
alert("Scanning failed: " + error);
}
);
}
};
It's basically the default Phonegap plugin panel. The problem is that it doesn't recognize the cordova.plugin.barcodeScanner. I've created the project trough the Phonegap Windows tool and ran the cordova plugin add cordova-plugin-statusbar command inside the folder. Please help me, I can't see any code example of this working. Thanks.
you can call getScanner() function onClick event in javascript Read More Here
function getScanner(){
cordova.plugins.barcodeScanner.scan(
function (result) {
alert("We got a barcode\n" +
"Result: " + result.text + "\n" +
"Format: " + result.format + "\n" +
"Cancelled: " + result.cancelled);
},
function (error) {
alert("Scanning failed: " + error);
}
); }
let me know if its not working..

notification popup with js/jquery

i've tried to create some notification message that should showing up anytime i have a new message. is done but the problem is if i refresh the browser then the message showing again. this is wrong. it should be hidden if already shows. does not matter if i refresh the browser again. it should be not show.
this is my code:
$(function(){
/* global MessageBus */
var name,
msgCube = $('.message_bus').data('queue') ;
MessageBus.ajax = function(args){
args["headers"]["X-NAME"] = name;
return $.ajax(args);
};
MessageBus.subscribe("/tasks" + msgCube, function(msg){
var obj = $.parseJSON(msg);
showMsg = function(){
var deffered = $.Deferred();
if(obj.state.viewed == 0){
dataModel = '<div class="msg">'
+ '<p>' + obj.task.name + '</p>'
+'<p>' + obj.task.description + '</p>';
$('.noticed').html(dataModel);
setTimeout(function () {
$(".noticed").fadeOut(300);
deffered.resolve();
}, 5000);
}
return deffered.promise();
};
//test don't show up after load
stopToLoad = function(){
console.log('load after');
$('.noticed').hide();
};
showMsg().then(function(){
stopToLoad();
});
//console.log(msg);
}, 0);
});
if you guys have an any sugestion, any solution, idea, i'll be glad and thanks for the Adviced.
best regard,

Why is my JavaScript code not working?

I keep getting the "Syntax Error: Unexpected identifier" JS error with this code:
function hashStuff() {
var messageID = window.location.hash.replace('#inbox-', '');
var msgSubject = $('#subject_' + messageID).html();
setTimeout("readMessage2(" + messageID + ", " + msgSubject + ");", 300);
}
if (window.location.hash) {
setTimeout("hashStuff();", 400);
}
I've also tried:
if (window.location.hash) {
function hashStuff() {
var messageID = window.location.hash.replace('#inbox-', '');
var msgSubject = $('#subject_' + messageID).html();
setTimeout("readMessage2(" + messageID + ", " + msgSubject + ");", 300);
}
setTimeout("hashStuff();", 400);
}
Neither of them work.
What I was trying to do was get information from the elements but I guess the page wasn't loaded yet so I need it to trigger after a second. I put it in a function so I can use a timeout and it will not work.
Any ideas? Thanks in advance.
If your messageID is something like 1234 and the msgSubject is Hello World, then the statement being evaluated is:
readMessage2(1234, Hello World);
Which, clearly, is incorrect and error-inducing.
The correct code is:
setTimeout( function() {readMessage2(messageID,msgSubject);}, 300);
You can run the script inside $(document).ready(function() {//script here}); . That will make sure that it is run after all the elements have loaded.
try wrapping your code inside ready block:
$(document).ready(function () {
//your code
});

Categories