VueJS not Rendering in Safari - javascript

Safari isn't rendering my single page application built in VueJS.
I have spent 2 weeks developing it. It contains components that show or not depending on user clicks. And data objects that are rendered via the "v-for" element.
In chrome all works perfectly!! In mozilla also...in safari the list doesn't show up. Why isn't safari rendering anything?? I can't even debug it..
I looked up work arounds, like polyfills...but these seem to not be supported by safari..so there's no point in implementing them.
Would love some support or insights guys..if there's no work around does that mean i have to go back a build it in JS + Jquery?
Thanks in advance

So, I had this same issue. Meaning, a series of components listed with a v-for but not rendered on the screen (or the DOM) only in Safari (on Mac) even though it worked just fine on Firefox and Chrome (even on Mac). And after long and hard attempts, I was able to resolve the issue. I will give the answer in two parts.
THE QUICK ANSWER
In my case, the render error was the end result of a date conversion gone wrong somewhere deep in my code in a helper file. Indeed, in this file, I was receiving an ISO date in string format and transforming it into a JS date object through new Date(myISODateString). While Firefox and Chrome handle this conversion just fine, Safari was producing 'Invalid Date' errors and the chain-reaction was only effecting a single component. Once I corrected this date parsing, everything was being rendered correctly in Safari. In this instance, I used Luxon to do the conversion, I will give that as the solution
DateTime.fromISO(myISODateString, { setZone: true }).toJSDate();
THE LONG ANSWER
I think what is even more valuable in this experience is how I found out that this was the problem since in your case, it will probably be some other particularity of Safari that is causing the error.
It was actually Frank Provost's comment on this question that guided me in the right direction.
It goes without saying that smaller components are most of the time constructed from their props. It is like their life source. If props are erroneous, internal operations and render will also be problematic.
So I decided to console, within the lifecycle hooks, the props that my non-rendering component was receiving. Of course, nothing was printed out to the console. So I went up one level above and did the same thing for the props of the parent component. This time, I was getting information in the console but there were variations in what is being printed to the console between Firefox and Safari.
By the way, the props were not filled in at created or mounted in my case since they depended on an asynchronous network operation. So, my console debugging looked like this;
created(){
setInterval(() => {
console.log(this.myProp);
}, 5000, this);
}
Long story short, by going up this way, component to component, variable to variable, I found out that I was relying on this date provided by my helper function in a helper file outside of my components and this was why no error was logged to the console at runtime even though multiple components were not being rendered correctly.

Related

Updated to Chrome v65 and started getting this error: Expected onClick listener to be a function, instead got type string

I have a React app that recently starting emitting this error.
https://reactjs.org/docs/error-decoder.html?invariant=94&args[]=onClick&args[]=string
Minified React error #94:
Expected onClick listener to be a function, instead got type string
When this error appears, none of our buttons/dropdowns work but the webpage isn't frozen. It only happens in one section of the app. When we navigate to another section and come back, the error does NOT appear again.
I've gone over every single onClick event in our app and there's not a single function that could possibly be passed in as a string or can be returned as a string. Although we have a few onClick events that can be passed a NULL object.
But we've narrowed down the steps that produced this bug:
It only started occurring when we updated to Chrome version 65, which only came out 2 days ago. The bug does NOT happen in previous Chrome versions (before v65)
It only happens in our production build of the React app, not on localhost (could it be a minifying error?)
The bug doesn't happen in our other apps, also built with React and minified with similar webpack configurations.
Does anyone have an idea of why this error is happening and how we can solve it?
Turns out it's specifically the minified/production build of React that's incompatible with Chrome65.
We flipped process.env.NODE_ENV back to 'development', until we find a better solution, or Chrome resolves the issue with v65.
Update: If you are using the toJS() HOC from redux (https://github.com/reactjs/redux/blob/master/docs/recipes/UsingImmutableJS.md#use-a-higher-order-component-to-convert-your-smart-components-immutablejs-props-to-your-dumb-components-javascript-props), the problem is with Object.entries().
To fix this for now, replace Object.entries with a custom entries function:
(ES6)
const entries = x => Object.keys(x).reduce((y, z) => y.push([z, x[z]]) && y, []);
You should be able to flip your NODE_ENV back to 'production'.
Currently trying to figure out why the wrappedComponentProps object causes the issue, but a regular object like { myFunc: function(){} } doesn't.
(Any help debugging this would be appreciated!)
Calling delete wrapperComponentProps[ANY-VALID-KEY] before running Object.entries() fixes the issue, so I suspect it's something to do with object security/caching.
I found a solution. I still think there was an error with Chrome v 65's minification process but I started deleting clickable components from my app until the error was gone to flush out the problematic component.
Turns out it was a <LinkContainer /> from react-bootstrap-router library that was causing the bug. We replaced with react-router link components and the error went away!

babel-polyfill messed with Object in IE11

I have a 1-year-old React app with Server Render that had been in production for a while,
However, it was detected a couple of days before that somehow, the app stop to work with IE11. This is really weird because we have been tested on IE11 many times and it worked before. We even try to roll back the project (using tagged docker image) and this error still appears.
The root cause appears to be in babel-polyfill that somehow change the way Object is created in IE11.
The created object will have jscomp_symbol_Symbol.toStringTag1" Array Iterator"
Here's what I found on the console:
try this input console.log({}) if you have IE11 it will output differently.
This somehow causing my web app to fail since every object will fail lodash _.isPlainObject which is the condition inside Redux.

Angular Universal and browser feature checks

When developing a web app with jQuery or normal JavaScript, it is commonplace to check for feature availability first. So for example, if I want to use the document.oncopy event, I should first have something like this to ensure my code doesn't break for lesser browsers:
if ("oncopy" in document) {
// Feature is available
}
I'm a bit puzzled about how this would work in Angular2. I could still use the same if I expect to only run in the browser, but I'm specifically told to leave the DOM alone if I want to use Angular Universal and depend on templates or the DomRenderer instead. This allows the page to be pre-rendered on the server and provides a truly impressive performance gain.
But suppose I want a specific div to be invisible if the document.oncopy is unavailable. My understanding is that this is not recommended:
<div *ngIf="hasFeature()">...</div>
and
hasFeature() {
return 'oncopy' in document;
}
because then I'm still manipulating the DOM. Note that my example is about the document.oncopy but I could choose any feature whatsoever that doesn't have universal support.
I tested this using Chris Nwamba's tutorial on Scotch and added the following to the end of his Home template:
<div *ngIf="hasFeature()">Feature is supported</div>
<div *ngIf="!hasFeature()">Feature is NOT supported</div>
Update: Interestingly, it gave different results on different browsers. On Chrome 55, it executed as it would normally and showed the "Feature is supported" message. On IE11, I received the "not supported" message. In both instances the server log shows a EXCEPTION: document is not defined message, but the page still seems perfectly okay.
So what is the correct way to check for browser features if I want to use Angular Universal?
Update:
I also toyed around with using a field in the template and assigning that field from one of the life cycle hooks. ngAfterContentInit seemed like a fine candidate, but also causes an error on the server. It still runs fine in the browser with no weird effects (that I have noticed so far).
There are two ways to approach this:
Do the check only once the server is done rendering and the client is completely initialised (including the replay of user events done by preboot.js).
Return a reasonable default when the page is running on the server and perform the actual check only in the browser.
I started looking at the first option, but none of the Angular2 life cycle events will help with this. In fact, you can clearly see them all executing on the server and only then on the client.
I then started looking for something usable in preboot.js but quickly realised it was more complex than it needed to be.
So onto option 2 I went. It turns out checking for the browser is as easy as importing and checking isBrowser.
import { isBrowser } from "angular2-universal";
#Component({
// All the usual stuff
})
export class MyComponent {
// ...
hasFeature(): boolean {
return isBrowser && 'oncopy' in document;
}
// ...
}
And then use the template as I showed in the question.
To check if you're running on the server, import and use isNode in exactly the same way. There doesn't seem to be an obvious way to distinguish between Node and ASP.NET Core, but perhaps it's best not to write too much code that specific to platform.

Lightning script error in Chrome and Firefox but not in IE

I'm so used to having things work in Chrome and Firefox and then having to be fixed in IE that this has me well and truly stumped.
I'm trying to get DataTables to work within a Lightning component and keep getting this error: Uncaught TypeError: Failed to construct 'Option': Please use the 'new' operator, this DOM object constructor cannot be called as a function. As you can see here:
A mate at work suggested I try it in IE and it all works fine:
So I guess my question has multiple parts, not only do I need to understand why it fails in Chrome (and Firefox, because it errors there as well) and how I might correct it, but I'd also really like to understand what's going on within Lightning for this to happen as it seems as though the culprit is aura_prod.js but I've checked the script in both environments and it's the same in each...
Any help greatly appreciated.
EDIT
Quite rightly it has been pointed out that I haven't included any code, I guess the reason I didn't is because it's trivial:
$("#example").DataTable();
which is called after the table has been generated as a static table.

Browser.ExecScript() stopped working after updating windows

I've set up a simple testbed for WatiN (ver 2.1) which reads:
var browser = new IE();
browser.GoTo("http://www.google.co.il"); // webpage doesn't matter really
browser.RunScript("alert(123)");
This works only if KB3025390 is not installed. Installing it breaks the above test with an UnAuthorizedAccessException which has HRESULT set to E_ACCESSDENIED. What gives? Is there any workaround?
Update: Using IWebBrowser2.Navigate2 along with "javascript:console.log(123)" type of scripts works however
it makes me feel uneasy using such a backchannel
the scripts run through this back-channel of .Navigate2() may only have a max length of about 2070 chars (give or take) otherwise they get forcibly truncated to this length leading to javascript errors upon attempting to run them
using .Navigate2(), even with the most trivial script, will clog the ready state of Internet Explorer for good in the sense that it will be set to READYSTATE_LOADING without any hope of getting rid of it. In simple terms this means that once you use this hack, you either have to perform every single subsequent operation in WatiN in a "dont-wait-for-webpage-to-load" fashion (GoToNoWait, ClickNoWait etc) lest your code freezes upon waiting for the browser to turn back to READYSTATE_COMPLETE (which will never come about ofcourse as already mentioned).
there appears to be a much broader issue here in the sense that I can't even access the properties of an IHtmlWindow2 object p.e. window.document throws an unauthorized exception again making it virtually impossible to transfer over to the C# world the return-values of the scripts I'm running (using Expando etc) for documents other than window.top.document (for the window.top.document window there is IWebBrowser2.Document which does the trick)
Update#2: The folks over at the selenium project have also noticed this issue:
https://code.google.com/p/selenium/issues/detail?id=8302
A bug report has been created as well:
https://connect.microsoft.com/IE/feedback/details/1062093/installation-of-kb3025390-breaks-out-of-process-javascript-execution-in-ie11
Update#3: IHTMLWindow2.setInterval and IHTMLWindow2.setTimeout also throw UnauthorizedAccess exceptions. These methods are not marked as deprecated in:
http://msdn.microsoft.com/ko-kr/library/windows/desktop/aa741505%28v=vs.85%29.aspx
yet they have wounded up suffering from the same cutbacks all the same.
Update#4: I gave the approach recommended in this post a shot:
https://stackoverflow.com/a/18546866/863651
In order to dynamically invoke the "eval" method of the IHTMLWindow2 object (or any other method really). Got the same "System.UnauthorizedAccessException" as above. So no joy here either.
Microsoft recommends using "eval" over "execscript" however after the above experiment I suspect that they are refering to accessing "eval" only from within the browser.
As far as I can tell thus far, when it comes to the full-fledged IE11+ using "eval" out-of-process (via COM) appears to have been completely prohibited along with any other function-invocation of the window object, the only exception being the back-channel of the .Navigate2() mentioned above.
It turns out Microsoft eventually backpedaled on its decision to kill off .execScript at COM-level. Just install the latest updates for Windows including kb3025390: One of the updates for IE that came after kb3025390 brings back .execScript functionality at COM-level
Note, however, that .execScript is not accessible through IE's javascript anymore. In that context it's gone for good.
fyi: this one is also not working
ieInstance.Document.Script.<methodNameString>(<commaSeperatedParameterString>)
try this worked for me at some places but not all places
ieObject.Navigate "javascript:<methodNameString>(<commaSeperatedParameterString>)", Null, "_parent"
or
ieObject.Navigate2 "javascript:"<methodNameString>(<commaSeperatedParameterString>)", Null, "_parent"
now trying to find out solution using eval
I have found a way around the problem of an update installing automatically. You can just create a simple batch file with following content.
{code}
#echo off
wusa /uninstall /kb:3025390/quiet /norestart
END
{code}
Then go to task scheduler, create a new task for this batch file to run every one hour or day as per your requirements. Add it as a system task so it runs in the background and does not affect the running automations.

Categories

Resources