1

PLEASE CONSIDER REMOVING THE DUPLICATE QUESTION FLAG. IT IS NOT A DUPLICATE QUESTION BECAUSE IT IS NOT ASKING HOW TO MODIFY STRINGS BUT ADDRESSES WHAT MAY BE A BUG RESULTING IN ERRORS BEING THROWN WHEN STRING METHODS ARE APPLIED TO STRINGS CORRECTLY. THE MISUNDERSTANDING MAY BE DUE TO NOT READING PAST THE SPECIFIC EXAMPLE I USED TO ILLUSTRATE THE PROBLEM (WHICH WAS REMOVING QUOTE MARKS FROM A STRING) BUT IS NOTHING TO DO WITH THE SPECIFICS OF THAT EXAMPLE. RATHER IT IS AN UNEXPECTED ERROR WHEN ANY STRING METHOD IS APPLIED TO ANY STRING IN THE PARTICULAR CIRCUMSTANCES DISCUSSED. THANKS.

(I know how to truncate or replace strings, string methods are not working here. I also know how to remove quotes from strings, this is NOT a repeat of the suggested question. While I appreciate help, please only answer if you read past the bit where I say I want to remove the quotes. I want to know why I get an error when I am using string methods correctly)

I have an array containing sets of data. A typical set (i.e. array element) is a string containing data pairs separated with commas. So the first element might look like this:

sets[0] = '"name":"dave","height":"tall","age":"old"'

Each element holds a string, not an array (and I have confirmed this by printing typeof for each element).

I process each element to form an array of its component parts by splitting at the commas:

let currentSet = sets[i].split(",");

so, for the sets[0] example, set[0] fills currentSet to be:

currentSet = ['"name":"dave"', '"height":"tall"', '"age":"old"']

and

currentSet[0] = '"name":"dave"';

I now want to extract the "dave" portion of each current set and push it to an new results array:

dat = currentSet[j].split(":")[1];
resArray.push(dat);

This works as expected and I get '"dave"' as a new element in the resArray.

The next part is proving difficult. Instead of pushing "dave" (with the literal quote marks) to the array, I want to push dave (without quote marks being in the string) to the array so instead of:

resArray = ['"dave"', '"tall"', '"old"']

I want:

resArray = ['dave', 'tall', 'old']

I have tried using dat.slice dat.substring and dat.replace to modify the string pushed to the array but all throw an error (can't apply string methods to null).

I'm not especially asking for solutions of how to achieve the result I want (although would welcome the neat solution that I have probably overlooked) but really want to understand why I cannot seem to process dat by any string method and push the result to an array. I should stress again that I have confirmed using typeof that each dat extraction is a string. This is driving me nuts. Any explanation would be most welcome.

Thanks.

My actual javascript lines (with the slice example) which processes each set of starting data:

for (var i = 0; i < sets.length; i++)
{
let currentSet = sets[i].split(",");
// e.g. sets[i] = '"name":"dave","height":"tall","age":"old"'
// e.g. currentSet = ['"name":"dave"', '"height":"tall"', '"age":"old"']
resArray[i] = [];

for (var j = 0; j < currentSet.length; j++)
{

dat = currentSet[j].split(":")[1];

resArray[i].push(dat.slice(1,dat.length-2)); // throws error
// resArray[i].push(dat) // works fine;
// resArray[i].push(typeof dat) // confirms dat type is string;

} // next subset j;

outArray[i] = resArray[i].join(",");

currentSet = null;

} // next sets i;
Dave Pritlove
  • 2,601
  • 3
  • 15
  • 14
  • Why would you not use JavaScript objects instead of that invented string syntax? – Pointy Aug 31 '19 at 00:41
  • *can't apply string methods to null* Can't reproduce given your code https://jsfiddle.net/6j4Lbuzp/ – CertainPerformance Aug 31 '19 at 00:43
  • you can replace the quotes using a simple regex `resArray[i].push(dat.replace(/"/g, ''))` – Panther Aug 31 '19 at 00:44
  • Nidhin - no. As I said, string methods don't work so it's not a repeat of that as it gives string methods. – Dave Pritlove Aug 31 '19 at 00:46
  • CertainPerformance - thanks, I looked at your jsfiddle but can't see any output or errors so don't know if I'm running it right there. I get errors in firefox and chrome. – Dave Pritlove Aug 31 '19 at 00:48
  • Panther - I can't get replace or any string methods to work, they all throw errors. The dat string will push fine until modified. – Dave Pritlove Aug 31 '19 at 00:55
  • `resArray.push(dat).replace('"','');` should do it – admcfajn Aug 31 '19 at 00:56
  • admcfajn - thanks but no. As I've said, all string methods, including replace, throw an error in firefox and chrome. – Dave Pritlove Aug 31 '19 at 00:58
  • 1
    The its not the issue with the methods, `dat` gets undefined somehow. May be you need to check `dat = currentSet[j].split(":")[1];` if it returns a correct value always – Panther Aug 31 '19 at 00:59
  • Panther - thanks. Yes, when I print the resArray after pushing dat to it, all the pushes are as expected (with the quotes). It is only when I process dat to remove the quotes (I've tried slice, substring and replace) that the error occurs. Thanks I was beginning to think I couldn't explain the problem as evreyone else has suggested all the things I thought I had explained I have already tried! – Dave Pritlove Aug 31 '19 at 01:11
  • CertainPerformance - I tried again with your jsfiddle and still don't get it working. I should have asked you - do you see an output when you run it there? When I run the jsfiddle, the white panel (which I assume is output) remains blank and I can't find any other output console. Do you see an output? Sorry I'm not familiar with jsfiddle so can't be sure I'm not looking in the right place but I don't see an output. Thanks. – Dave Pritlove Aug 31 '19 at 10:30

2 Answers2

1

This should work. I added some variables for your code to function.

sets = [];
resArray = [];
outArray = [];
sets[0] = '"name":"dave","height":"tall","age":"old"';
for (var i = 0; i < sets.length; i++)
{
let currentSet = sets[i].split(",");
// e.g. sets[i] = '"name":"dave","height":"tall","age":"old"'
// e.g. currentSet = ['"name":"dave"', '"height":"tall"', '"age":"old"']
resArray[i] = [];

for (var j = 0; j < currentSet.length; j++)
{

var dat = currentSet[j].split(":")[1];

resArray[i].push(dat.slice(1,dat.length-1)); // throws error
// resArray[i].push(dat) // works fine;
// resArray[i].push(typeof dat) // confirms dat type is string;

} // next subset j;

outArray[i] = resArray[i].join(",");

currentSet = null;

} // next sets i;

The problem, is that you are removing 1 too many chars from the end of each string that you are adding to resArray. Just change that from -2 to -1, and it works. I don't know what errors you could possibly be getting. Just ran this code into the dev console in chrome.

Edit

Ok this is the edit to fix the problem. We had to do some hacky stuff to get this to work for some odd reason, so this may not make sense but to edit the dat variable, just cast it to a string like this: dat = ""+dat I left the other code above incase anyone else needs help with this same problem.

WhiteFire356
  • 92
  • 2
  • 8
  • Thanks but I can't get any string methods to push in firefox or chrome regardless of how many characters I slice off or from where. Likewise with the replace or substring methods. Firefox gives "TypeError: dat is undefined" Chrome gives: "Uncaught TypeError: Cannot read property 'substring' of undefined" (or slice or replace, depending what method I use). – Dave Pritlove Aug 31 '19 at 00:52
  • To fix the dat undefined, you can just change "dat = currentSet[j]...." to "var dat = currentSet[j]...." And for the chrome error, I don't even understand that, because nowhere in the code is 'substring' being called. I should also mention, that to test if it worked, just console log outArray, or resArray – WhiteFire356 Aug 31 '19 at 01:05
  • Just copy the exact code I have above, open dev console and it will work. Unless your running a very outdated version on chrome. Also been tested in firefox. – WhiteFire356 Aug 31 '19 at 01:08
  • WhiteFire - thanks for the suggestions. dat was declared before the snippet I posted. I have the newest updates of firefox and chrome and get errors in both. In any case, string methods have existed for years and should work in any browser. Substring is not in the specific example I posted but is one of the three string methods that all throw errors when I try to modify day (slice, substring and replace all throw errors) Console is of no use as I am rendering data in a web page. Thanks anyway. – Dave Pritlove Aug 31 '19 at 01:16
  • David, if you could please specify more details about your execution environment, I could probably help you further (as well as other people). You seem to be getting many errors that other people just aren't getting. – WhiteFire356 Aug 31 '19 at 01:21
  • WhiteFire - I'm on a Macbook Pro running Firefox Quantum 68.0.2 (64-bit) and chrome Version 76.0.3809.132 (Official Build) (64-bit). Both are up to date. My output is to a webpage. I appreciate your help. It's beginning to look like I'm jinxed with some gremlin on my machine and it seems like my question is about to, wrongly, be closed because people think I'm asking how to remove quote marks! Thanks. – Dave Pritlove Aug 31 '19 at 01:35
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/198751/discussion-between-whitefire356-and-dave-pritlove). – WhiteFire356 Aug 31 '19 at 02:23
  • WhiteFire - sorry I had to sleep, it was after 3.am. here. I did some more experiements and am no further advanced except to have confirmed that if I apply ANY string method to dat after is extracted from the currentSet[j] split, it throws an error despite typeof dat returning string. I'll try and get on a different machine today but otherwise will probably find a different strategy altogether. Thanks again. – Dave Pritlove Aug 31 '19 at 10:26
  • I have a horrible work-around that allows me to turn dat (supposedly a string - confirmed by typeof but unmodifiable by string methods) into a string that can be modified without error. – Dave Pritlove Aug 31 '19 at 11:31
  • the horrid work-around is: On the line after assigning dat its value (extracted as index 1 of an array) I catenate a character to both ends: dat = "x" + dat + "x". Now if I apply .slice, .replace or .substring to dat, it works without problem so it is now recognised as a string. It's absolutely horrible but it works. I'd still appreciate ideas even though the nasty work-around works. Thanks everyone. – Dave Pritlove Aug 31 '19 at 11:40
  • 1
    wow that is crazy I don't even understand why that works. Instead of doing that, you could just do some normal string casting like this: `""+dat` That should still cast it to a string without adding any chars to the string. – WhiteFire356 Aug 31 '19 at 14:20
  • WhiteFire - that's an excellent idea and it works! Not having the unnecessary characters simplified my final processing significantly. Thanks very much. I think it will remain a mystery but sometimes we just need to get it to work. Thanks again. – Dave Pritlove Aug 31 '19 at 19:45
  • David - Ok, I edited the answer to fix your problem. If it indeed works, then it would be very helpful if you would accept my answer. Sorry for getting marked as duplicate as it definitely isn't! (: – WhiteFire356 Aug 31 '19 at 22:08
  • WhiteFire - I upvoted your answer but, because my question's been marked as duplicate, I don't have an accept button, sorry. I can't find a way to contact the people who marked it as duplicate and the help pages said to edit the question requesting reconsideration, so I will just have to wait. Thanks. – Dave Pritlove Sep 02 '19 at 12:05
  • No problem! Just glad to help out (: – WhiteFire356 Sep 04 '19 at 03:03
0

Using replace is the simplest way to remove an expression or character multiple found multiple times in a string in my opinion. If you provide a specific value, it will only replace it on its first occurrence, However, when using a regex, it will replace all the matches found. If you replace your line by the following, your code will behave as expected:

resArray[i].push(dat.replace(/"/g, ''));
David
  • 134
  • 13
  • David - no, I get an error. I know how to process strings but what seems straight forward is throwing an error. Thanks anyway. – Dave Pritlove Aug 31 '19 at 01:03
  • For testing I used variable declarations similar to the previous answer. (using slice or replace in that example works) Try to make sure your variable declarations are ok and compare them with the answer above. Your array currentSet might be empty at some point or .split(':')[1] might return null because a string in the set does not contain any ':' which would abort the execution by throwing the error you mentioned above because dat would be null. For testing purposes you may want to try implementing a try catch block around your splice/replace and see if it returns anything. – David Aug 31 '19 at 01:32
  • David - when I run the same code without applying any string methods to dat, it works fine. Everything is declared and dat returns as expected. It is when I slice, substring or replace dat that it throws an error when I push the result to the array. Very odd. – Dave Pritlove Aug 31 '19 at 01:40
  • yeah that's odd, since a couple of us seem to have made it work on our side with the same code, it has to be related to your execution environment somehow. I'm very intrigued by this. This might sound like a dumb question but, are you running your script from your html file or did you import a js file to it? If you did an import, maybe the cache didn't clear on reload and you're still running an old version of your script that used to crash. – David Aug 31 '19 at 02:04
  • David - I have a simple html file containing a text area into which I paste JSON data to be processed. A script in the html file (not external) splits the JSON text into the sets array and should send the cleaned up data I need to a second text area on the webpage. I've tried rebooting and also follow all failures with an edit to process push the unmodified dat (which always works fine). I'll try on another machine tomorrow. It's bizarre. – Dave Pritlove Aug 31 '19 at 02:15
  • Quick follow up as I eventually resolved this problem and, although marked as duplicate and closed, it was never a duplicate and may affect other users. When I ran the same code on other machines it was fine. When I reviewed recent installs on the affected machines, the only suspect was VS Code, updated the previous day. I removed this and the problem went away. Fresh install of VS Code didn't reproduce the problem either. Lesson, sometimes there really are bugs outside of our control (as there are SO moderators who ignore explanation of their misunderstanding). – Dave Pritlove Mar 14 '22 at 11:44