How does React deal with pre-compiled HTML from PhantomJS? - ajax

I compiled my reactjs using webpack and got a bundle file bundles.js. My bundles.js contains a component that make API calls to get the data.
I put this file in my html and pass the url to phantom.js to pre-compile static html for SEO reasons.
I am witnessing something strange here, the ajax calls for APIS are not getting fired at all.
For example, I have a component called Home which is called when I request for url /home. My Home component makes an ajax request to backend (django-rest) to get some data. Now when I call home page in phantomjs this api call is not getting fired.
Am I missing something here?

I have been using React based app rendering in Phantomjs since 2014. Make sure you use the latest Phantomjs version v2.x. The problems with Phantomjs occur because it uses older webkit engine, so if you have some CSS3 features used make sure they are prefixed correctly example flexbox layout.
From the JS side the PhantomJS does not support many newer APIs (example fetch etc.), to fix this add the polyfills and your fine. The most complicated thing is to track down errors, use the console.log and evaluate code inside the Phantomjs. There is also debugging mode which is actually quite difficult to use, but this could help you track down complex errors. I used webkit engine based browser Aurora to track down some of the issues.
For debugging the network traffic, try logging the requested and received events:
var page = require('webpage').create();
page.onResourceRequested = function(request) {
console.log('Request ' + JSON.stringify(request, undefined, 4));
};
page.onResourceReceived = function(response) {
console.log('Receive ' + JSON.stringify(response, undefined, 4));
};

Related

Vuepress oidc-client preventing build

It looks like Vuepress is made for public docs, but we decided to add client and server security to protect some of the doc pages. But unfortunately although oidc-client (https://github.com/IdentityModel/oidc-client-js/wiki) works during dev, it throws exception when build.
I get ReferenceError: window is not defined and when I try to trick the compiler with const window = window || { location: {} }; I get TypeError: Cannot read property 'getItem' of undefined
Any idea how to make this work?
This was driving me nuts also. I discovered the component I was trying to add was looking at window.location in its code - this was triggering the error.
My understanding is that the build process has not access to Browser things like window etc.
As soon as I removed the window.location bit from my code things built just fine and all is well.

Should I use HTTP or xmlhttprequest on node.js? When?

I'm still exploring REST, node.js and generally web development. What I found out is that xmlhttprequest is mostly(if not always) used when using AJAX. As I learned AJAX is for asynchronous Javascript and XML. So my question is should I be using xmlhttprequest in my node.js project, just when I want to do asynchronous parts on my webpage? or does node.js HTTP also have opportunity to asynchronous javascript? How can I balance well the use of HTTP and xmlhttprequest(or AJAX) so that I don't get too messy in all my REST API stuff?
P.S. I kinda don't want to use AJAX, because of XML. I have heard that XML is much heavier in data than JSON and isn't worth using anymore. Is it true? What would you recommend me to do?
non async on node?
you're trying to build an endpoint api so all the other cases of not using async should be thrown out the window. As soon as you have a single non async code in your node.js project it will freeze the entire process until it is complete. Remember Node.js runs a single Thread (theoretically) which means all the other concurrent users are gonna get frozen.. that's one way to make people really upset.
say for instance you need to read a file from your Node.js server on a get request from a client (let's say a browser) well you want to make it a callback/promise never do non-async with an API server there is just no reason not to (in your case).
example below
import * as express from "express";
import * as fs from 'fs';
let app = express();
app.get('/getFileInfo', function(req, res) {
fs.readFile('filePath', 'UTF-8', function(err, data) {
if (err) {
console.log(err);
res.json({error: err});
} else {
res.json({data: data});
}
})
});
//users will freeze while the file is read until it is done reading
app.get('/nonasync', function(req, res) {
let data = fs.readFileSync('path', 'utf-8');
res.json({data:data});
});
the exact same idea applies to your web browser.. if you are going to not do something async in the browsers javascript the entire web application will be unresponsive because it also runs in the same manner, it has one main loop and unless they are in callbacks/promises/observable the website will freeze. Ajax is a much neater/nicer way to implement post/get/put/delete/get:id from a server then an XMLHttpRequest. now both of these have an option to send and receive JSON not only XML. Ajax is safer due to supporting different browser compatibility specs as XMLHttpRequest has some limitations in IE and Safari I believe.
NOTE: if you're not using a framework with node.js you should, it helps keep your endpoints neat and testable along with being able to pass the project on to others without them having to learn the way you implemented your req, res structure
some frameworks for node
Express 4 (my preference, api doc is really really good and strong
community)
Restify (used by Netflix - really light)
Hapi (never used but heard of)
some frameworks for web browsers you might like
angular 2 (my preference as I'm from a MEAN stack)
reactJS (created by big blue Facebook)
knockoutJS (simple and easy)
all the browser frameworks have their own implementation of the RESTful api's, but more are leaning towards Observable objects.

History issue combining WP7.5, phonegap and jqm

I have a phonegap app that uses jqm that works fine in android and ios.
Porting to WP7 i have an issue with the history, specifically history.back() (but also .go(-1) etc). This refers to going back in history where the previous 'page' was in the same physical html file, just a different data-role=page div.
using a jwm site in a regular browser is fine (with separate 'pages' in the same html file). Also, using history.back() when we go from one html file to another in the app is fine. It's the specific combination of WP7.5, jqm and PG.
Has anyone come across a solution for this? it's driving me crazy, and has been as issue since PG 1.4.1 and jwm 1.0.
EDIT 1: It's possible that the phonegap process of initialising the webview on WP7.5 somehow overrides the jqm history overrides, after they've loaded.
EDIT 2: definitely something to do with jqm not being able to modify the history. each time there is a 'page' change, history.length is still 0.
EDIT 3: When i inspect the 'history' object, i found there is no function for replaceState or pushState - i know jqm uses this for history nav, maybe that's the problem.
ok - this isn't perfect, but here's a solution (read: hack) that works for me. It only works for page hash changes, not actual url changes (but you could add a regex check for that). Put this somewhere in the code that runs on ondeviceready:
if (device.platform == 'WinCE') {
window.history.back = function () {
var p = $.mobile.urlHistory.getPrev();
if (p) {
$.mobile.changePage("#" + p.pageUrl, { reverse: true });
$.mobile.urlHistory.stack.splice(-2, 2);
$.mobile.urlHistory.activeIndex -= 2;
}
}
}

Wibiya toolbar breaks Drupal quicktabs

I have the Drupal Quicktabs module installed at:
http://ar.sacherokeedev.com/auction-directory
I've also installed the wibiya toolbar, http://www.wibiya.com.
Everything works fine in Firefox and Chrome, but in IE7, with the toolbar enabled, it breaks the ajax tab loading. With the toolbar disabled, IE7 works fine. Wibya has a "Javascript Conflict" mode, and I've tried that as well as changing my DocType, as they suggest.
I've narrowed it down to a couple of things. First, quicktabs behavior is based on the "type" of the tab:
if (tab.tabObj.type != 'view') {
// construct the ajax path to retrieve the content, depending on type
var qtAjaxPath = Drupal.settings.basePath + 'quicktabs/ajax/' + tab.tabObj.type + '/';
switch (tab.tabObj.type) {
case 'node':
qtAjaxPath += tab.tabObj.nid + '/' + tab.tabObj.teaser + '/' + tab.tabObj.hide_title;
break;
case 'block':
qtAjaxPath += tab.qtid + '/' + tab.tabObj.bid + '/' + tab.tabObj.hide_title;
break;
case 'qtabs':
qtAjaxPath += tab.tabObj.qtid;
break;
}
In my case, when using the toolbar in IE, tab.tabObj.type is "undefined". So, I'm thinking that wibiya is hijacking my objects or something.
I also get a runtime error, "Object does not support this property or method" in the following block:
if (!Drupal.quicktabs.scripts[files[i]] && !files[i].match(/^\/misc\/jquery\.js.*$/)) {
Drupal.quicktabs.scripts[files[i]] = files[i];
html += '<script type="text/javascript" src="' + files[i] + '"></script>';
}
Has anyone seen this before, or have any suggestions?
Update: I did console.log(tab.tabObj) and in Firefox and Chrome, I get something that makes sense, an Object with a block id, a type, etc... But in i.e. I get this:
function(fn,thisObj){var scope=thisObj|window;for(vari=0,len=this.length;i<len;++i){fn.call(scope,this[i],i,this);}}
Anyone have any ideas?
UPDATE: I am currently using the Drupal specific wibya module, and the toolbar itself works fine on my site whether one is using IE, Firefox or Chrome. The issue is that the ajax tabs on that page are prevented from functioning by the wibiya toolbar. I'm inclined to agree with #clive that it's a jQuery/javascript conflict, but I'm not sure what I can do about it.
As for running Drupal 6, I inherited the system, and as of now, can't upgrade.
UPDATE: I just tried loading jQuery 1.4 using the instructions at http://drupal.org/node/1058168. That caused IE to work properly, but now Chrome and Firefox don't like it.
UPDATE: This is a conflict between jQuery 1.3 which runs on Drupal 6 and the Wibiya toolbar which uses at least 1.4. I'm accepting #clive's answer, mainly because he's right about the fact that this is just something that I'm going to have to live with if I have to keep using Drupal 6.
My best guess would be that you're using Drupal 6 which ships with jQuery 1.2.6 (or 1.3.2 with the jQuery update module. The Wibiya baar conversely uses jQuery 1.4.2 upwards.
According to a page on the Wibiya support forums (which I'm sure you've already seen):
if page loads another version of jQuery like 1.2.6 or 1.3.2 previously, Wibiya bar's loading of its own jQ 1.4.2 does not work. No bars, nothing.
But if you load your own jQ 1.4.2 in the first place, then your bar works, despite all other Drupal functions suck like polls, votes, hierarchical select tags, nice menus, some collapsibles, etc.
There a lots of these types of problems with Drupal which is why the community comes up with workarounds and solutions: The Drupal specific Wibiya module will probably save you a lot of headaches.
UPDATE
There's a JS error on your site:
Unsafe JavaScript attempt to access frame with URL http://ar.sacherokeedev.com/auction-directory from frame with URL http://ad.doubleclick.net/adi/N1727.autoremarketing.com/B5111890.6;sz=728x90;click=http://adclick.g.doubleclick.net/aclk?sa=L&ai=B6dLCjz5qTqvUGIfN0AXN67WqBa-C-usBAAAAEAEg7ZqAFjgAWK_Q_80gYLu2moPQCrIBFGFyLnNhY2hlcm9rZWVkZXYuY29tugEJZ2ZwX2ltYWdlyAEJ2gEtaHR0cDovL2FyLnNhY2hlcm9rZWVkZXYuY29tL2F1Y3Rpb24tZGlyZWN0b3J5mAKgjQbAAgLgAgDqAhNBUl9Ib21lX0xlYWRlcmJvYXJk-ALw0R6QA4wGmAPgA6gDAeAEAaAGFg&num=0&sig=AOD64_1Xi82LSwUc1kKF0RL_orTztOMfxg&client=ca-pub-2649455708539916&adurl=;ord=1670303729?. Domains, protocols and ports must match.
Is it possible that unsafe frame attempt is stopping IE7 from processing the rest of the JS, thereby making your tabs not work?

Flash + fancy uploader.. have to click twice on firefox

http://digitarald.de/project/fancyupload/3-0/showcase/attach-a-file/
That's the uploader plugin I'm using.
If you go there in firefox, you'll notice you have to click "attach a file" twice before it works. It seems to work fine in every other browser (that I've tested).
it's creating a flash object, and I'm not sure how to go about making it so you only click once in FF.
I'm not familiar with mooTools, but have you tried something like this? (attempted to write it in mooTools, but have no idea what I'm doing).
$('uploadLink').addEvent('click', function(){
if(Browser.firefox) $('uploadLink').fireEvent('click');
});
or I suppose if it has to wait for the flash to be created, something like this:
$('uploadLink').addEvent('click', function(){
if(Browser.firefox){
var flashTimer = setTimeout(function(){
clearTimeout(flashTimer);
/// or however you make sure the flash has successfully been added to the page
if($('flashContainer').getElements().length) $('uploadLink').fireEvent('click');
},100);
}
});
There's always the possibility that FF's security measures won't let you do something like this (mouse interactions with flash can be potentially harmful, as flash has FS access and stuff).
Depending on what your backend is, I'm highly in favor of skipping flash for file uploads when possible. One very well written plugin for such a task is available here:
http://valums.com/ajax-upload/
Good luck!

Resources