Forum Moderators: open

Message Too Old, No Replies

"Cannot read properties of undefined" in a third party script

         

csdude55

6:17 am on Aug 20, 2022 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I'm using "fineuploader" (a third party script) to allow users to upload images. One such page is throwing this error in the console:

Uncaught TypeError: Cannot read properties of undefined (reading 'uuid')
at qq.FineUploader._addCannedFile (<anonymous>:1587:39)
at qq.FineUploader._addCannedFile (<anonymous>:6672:64)
at <anonymous>:1270:26
at qq.each (<anonymous>:685:34)
at qq.FineUploader.addInitialFiles (<anonymous>:1269:20)
at qq.FineUploader.addInitialFiles (<anonymous>:6173:56)
at w.fn.init.delegateCommand (<anonymous>:123:42)
at HTMLDivElement.<anonymous> (<anonymous>:138:50)
at Function.each (jquery.min.js:2:2573)
at w.fn.init.each (jquery.min.js:2:1240)


That doesn't explicitly reference a file on my server so it's hard to track down, but the only reference I can find to "_addCannedFile" and "uuid" is this:

qq.basePrivateApi = {
_addCannedFile: function(sessionData) {
var self = this;
return this._uploadData.addFile({
uuid: sessionData.uuid,
[more stuff that I don't think matters for this post]
});
},
[1100 more lines of stuff]
};


On the initial load of the page, "uuid" will not have been created. But I thought that would return false, not undefined?

Correct me if I'm wrong, but "uuid" here is a literal word, not a variable? Same as if I'd used "sessionData['uuid']". If that's correct then it's not an issue of failing to define uuid somewhere, but an issue of sessionData not being defined.

If that's the case, then maybe the fix is as simple as declaring it as an empty object:

qq.basePrivateApi = {
_addCannedFile: function(sessionData = {}) {
...
}
}


I'm VERY hesitant to modify a third part script that's super complex, but this feels like a pretty innocent modification that can't possibly have negative side effects... right?

robzilla

8:08 am on Aug 20, 2022 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



There needs to be a place where the _addCannedFile function is called. That's where I'd look, since apparently it gets passed something that doesn't have any properties.

csdude55

6:01 pm on Aug 20, 2022 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



There are several references to it, and it sends a variable "cannedFile".

A simple search for "cannedFile" in all of the .JS files in fineuploader is too broad, there are a ton of variables like "_addCannedFile" and "cannedFileList" that are irrelevant. I did a search for "(cannedFile" and the only thing relevant was this:

(function() {
"use strict";
qq.basePublicApi = {
[...],
addInitialFiles: function(cannedFileList) {
var self = this;

// HERE
qq.each(cannedFileList, function(index, cannedFile) {
self._addCannedFile(cannedFile);
});
},
[...]


I think that means that it's calling "cannedFileList()" to build "cannedFile" :-/

So a search for THAT leads me to:

(function() {
"use strict";
qq.uiPublicApi = {
addInitialFiles: function(cannedFileList) {
this._parent.prototype.addInitialFiles.apply(this, arguments);
this._templating.addCacheToDom();
},
[...]


and "addCacheToDom()" leads me to:

addCacheToDom: function() {
fileList.appendChild(fileBatch.content);
fileBatch.content = document.createDocumentFragment();
fileBatch.map = {};
},


Now I'm starting to get lost because I don't understand this format of calling a function, or what this._parent.prototype.addInitialFiles.apply(this.arguments) does. I guess that "arguments" is equivalent to "cannedFile", so maybe I need to ensure that "arguments" exists?

Meaning, maybe this modification:

(function() {
"use strict";
qq.uiPublicApi = {
addInitialFiles: function(cannedFileList) {

// no idea where "arguments" comes from, so this is a guess
arguments = arguments || false;

this._parent.prototype.addInitialFiles.apply(this, arguments);
this._templating.addCacheToDom();
},
[...]

csdude55

5:28 pm on Sep 2, 2022 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I've been digging on this for about 2 weeks now :-/

In the qq.uiPublicApi function, I used console.log(typeof arguments) to discover that "arguments" is an object. So I tried adding arguments = arguments || {};, but it had no apparent impact and I still had the "Cannot read properties..." error.

After that I went back to modifying the _addCannedFile... function? Or whatever it is.

All three of these modification seemed to work to fix the error, but caused another glitch :-/

// declare sessionData as an object by default
_addCannedFile: function(sessionData = {}) { ... }

// similar but different, declare sessionData as an object if it doesn't exist
_addCannedFile: function(sessionData) {
sessionData = sessionData || {};
...
}

// Optional Chaining Operator, a new one for me
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
//
// add a ? after each reference to sessionData so that it doesn't throw an error
return this._uploadData.addFile({
uuid: sessionData?.uuid,
...
})


So either of those seem to be a working solution to the original question, but now I'm lost on the new error! I'll create a second thread for it so that I don't confuse future readers; I'll include "fineuploader" in the subject, so if you find this thread specifically trying to modify that script then just look in the Javascript forum for "fineuploader".

robzilla

5:53 pm on Sep 2, 2022 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



If it happens on one page and not on others, what's the difference between the pages? Or is it not working anywhere?

csdude55

6:21 pm on Sep 2, 2022 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



It happens on every page. The problem is that I'm dealing with 5MB of code in 42 separate files, written by a third party, with little to no documentation! That makes it exceptionally hard to figure out what's going on.

robzilla

9:38 pm on Sep 2, 2022 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Can you replace it with a script that's not EOL?

Kendo

11:01 pm on Sep 2, 2022 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I had a similar problem with a JS that threw an error because it could not find the ID number for the "country" field. The ID number and country input was in the page code, just not being displayed at that stage because it was not included until the earlier part of the form was submitted.

csdude55

5:46 am on Sep 3, 2022 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Can you replace it with a script that's not EOL?

I'm open to suggestions! This script looks great and is easy to use (a HUGE bonus for my less-than-savvy users), but it's super complicated to implement and I've spent a LOT of time making it work! I hate to abandon it now, but I realize that I'll probably have to change it within a few years anyway :-/

The biggest value to this script is the ability for the user to select multiple pics to upload at once.

NickMNS

10:49 pm on Sep 15, 2022 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



uuid is an object property. And the error is telling you that the object is undefined. Based on the code above my guess is that the object
sessionData
is the one that is not defined.

A quick fix that I don't recommend but seems to be what your trying to do, would be to change:
uuid: sessionData.uuid
to read
uuid: sessionData && sessionData.uuid || false

I'm not sure if this will break anything else in the code but it will resolve the immediate bug. What I would guess is that whatever is populating sessionData (I have know idea what) hasn't had time to load and thus is undefined. So if there is away to delay the calling of the script it may resolve the issue without the changes above. It would also explain why it is occurring on some pages and not others.

csdude55

3:59 am on Sep 16, 2022 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



@NickMNS, I think you missed earlier where I said that I was gonna create a second topic. You're right that adding the "|| false" fixed the immediate problem, but then just caused another one :-/

The second solution was to change a predefined variable from an array to an object (eg, declaring it as "imgObj = {};"), but that caused yet another error! It all just keeps cascading down the line, but none of it is fatal so I eventually set it aside to worry about in the future.