[SOLVED] List with rows cannot be accessed by common JS syntax; '.data'

Can you show us the example from Stackoverflow that you are getting this data property from please?

Ok, let us turn the whole thing upside down and forget versions and parallel JS-communities. If a Stackoverflow example of 2018 does not comply with present PlayCanvas, then what to use in order to write to a .csv-file and save it? (being my main goal)
I have already tried out 3-4 of the examples in the stackoverflow example, without luck (and mainly due to JS-versions/age of the early examples (6-9 years old)).

I’m assuming this is the Stackoverflow answer you are using? https://stackoverflow.com/questions/44440208/how-to-remove-the-when-converting-javascript-object-to-csv-file/44440316

If so, the function converts an array of objects to a CSV file. The args function param is an object that has .data as the array as well as other properties.

Example project using the StackOverflow answer above: https://playcanvas.com/editor/scene/924158

Prints:

name,phone
"steven","0000000"
"foo","111111"
"bar","222222"
1 Like

The ressource was/is: https://stackoverflow.com/questions/14964035/how-to-export-javascript-array-info-to-csv-on-client-side

  • but still relevant in regards to the usage of ‘args’.
    (I haven’t used the ‘args’-approach so much in general - will get back later)

It’s a custom object they are passing as arguments to a function:

myFunction({ 
  filename: 'filename.csv',
  data: [1, 2, 3],
  columns: [a, b],
  myOtherCustomProperty: [4, 5, 6]
});

myFuction = function (options) {
   console.log( options.data )            // [1, 2, 3]
   console.log( options.myOtherCustomProperty )    // [4, 5, 6]
}

As you can see, .data is something they came up with as a name for their property. They could as well call it .myData. It is not part of standard js Array type, but a name of their own custom property.

2 Likes

Tried that answer too and that works fine too.

Modified my project to have a button that downloads a CSV file. https://playcanvas.com/editor/scene/924158

Just to run off @LeXXik’s post. Taking this answer from that thread: https://stackoverflow.com/a/34043817

        var csv = convertArrayOfObjectsToCSV({
            data: stockData
        });

You can see here that they create a new object, with the property data that references stockData which is an array of objects to the function that converts it the CSV.

It works

Still (hmmm … JS sometimes :-/ )

How to make it with a push-structure instead?
I am trying to make the following work:


        var example_outCSVArray = [ ];
example_outCSVArray.push({name: 'steven', phone: '0000000'});
        example_outCSVArray.push({name: 'stn', phone: '00yt67600'});
        example_outCSVArray.push({name: 'en', phone: '04540'});
  • or by inducing by object:
  var valueToPush = {};
valueToPush.name = 'steven'; valueToPush.phone = '000000';
        example_outCSVArray.push(valueToPush);

Both gives me the err: “Uncaught TypeError: item[key].replace is not a function” as error at the line of:

result += '"' + item[key].replace('\"', """) + '"';

Tried both methods, both work in my example: https://playcanvas.com/editor/scene/924158

ps: approach of https://stackoverflow.com/questions/34089353/push-to-multidimensional-array-in-javascript

  • does not seem to help either …

var example_outCSVArray = {name:[], phone:[] };
example_outCSVArray.name.push(‘Steven’); example_outCSVArray.phone.push(‘0000’);
example_outCSVArray.name.push(‘Stn’); example_outCSVArray.phone.push(‘005675600’);
example_outCSVArray.name.push(‘Sn’); example_outCSVArray.phone.push(‘0003420’);

The CSV conversion code that I copied can’t handle non string values. So something like this:

        exampleArray.push({name: 'world', phone: 234146});

Breaks it as phone is not a string and therefore doesn’t have a replace function. This is pretty easy to fix though.

ok, then

Forget those (they are meta within my debugging)
Let me ask in another way; my values are int’s and not strings -> should I make them strings in order to make it work? (trying it now - just quite contra-intutitve)

Modify the CSV conversion code so that it converts to strings before using the replace function.

Edit: ie:

result += '"' + item[key].toString().replace('\"', """) + '"';

Works (discouraged by the err-msg, though … hard to come to same conclusion as you, if seen for first time - as for me :slight_smile: ) … one has to understand the csv-parsing

Anyways, I have to state:

Reformulating: "ok, get that ‘PC-JS’ === vanilla JS (ES5) " … to “ok, get that ‘PC-JS’ == vanilla JS (ES5)

  • as the surrounding PC-structure still makes it a little different “someScr.prototype.someName = function() {” … etc

That’s the default structure for a class in ES5 (https://www.accelebrate.com/blog/javascript-es6-classes-and-prototype-inheritance-part-1-of-2/)

ok, getting to the most constructive island then; what you are saying is that I should add “ES5” to all my “js” google searches from now on?

Depends on what browsers you are targeting. You can write in ES6 if you want (the linter might complain but you can disable that with a specific comment at the top of the file).

The PlayCanvas engine is written in ES5 but doesn’t stop the developer from using ES6 if they want.

All engine code, the scripts that the developer creates has to run as is in the browser. At most, the PlayCanvas build system will minimise the code and concatenates the scripts into one large one in an order that the developer can define in project settings.

I run through the thought process when I was debugging this as you posted it.

Looking at the error message, it’s saying that replace is not a function of item[key]. Looking at the CSV code, item is an entry of the array of objects that we passed in so item[key] is one of the properties of the object.

Judging from how the replace function is used, it looks like a string replace function.

Test the theory and see what happens when I pass a number instead of string. Crashes.

Looks like an easy fix. Just has to make sure that we convert the value to a string before using the replace function.

result += '"' + item[key].toString().replace('\"', """) + '"';

Test with previous fail case. Looks like it works.

1 Like