Link to home
Start Free TrialLog in
Avatar of RationalRabbit
RationalRabbit

asked on

Transfer data from PHP array to JavaScript in another file

After processing data, I am trying to send results back to one of three pages, depending on what is being processed and the results. I thought it would be a simple matter to send the data to be picked up by a JavaScript file to display in an alert window. My Web console is giving me the following error:
SyntaxError: "" string literal contains an unescaped line break
There are no line breaks in the content. It is just one small string of text.
However, alternatively, if there are errors, I need to send an array to display those errors.
When I try to encode that array, I get the following error:
SyntaxError: expected expression, got '%'
The encoded string looks like this: "%5B%22Source%3A+%22%5D"

Perhaps there is just a more intelligent way to do this. I could just create my own window in PHP and forget about the alert, but I already use this alert process for include files so it would be nice if I could use the same result processing.

Here is what I am doing with the results of the remote file:
(First, the function for the code below)
<script type="text/javascript">
   function AddParameter(form, name, value)
   {
      var $input = $("<input />").attr("type", "hidden").attr("name", name).attr("value", value);
      form.append($input);
   }
</script>

Open in new window

$Act (for "action") is the file the data will return to.  $AppID is just a record number.
This is really one less redundant code set, but easier to show this way. It either sends a result message or errors.
<?php
   if(count($Error) > 0)
   {
      echo('
      <script type="text/javascript">');
         $js_Error = urlencode(json_encode($Error));
         echo('
         var Error = "'.$js_Error.'";');
         echo('
         var $form = $("<form/>").attr("action", "'.$Act.'").attr("method", "post");
         $("body").append($form);
         AddParameter($form, "Error", Error);
         AddParameter($form, "AppID", "'.$AppID.'");
         $form[0].submit();
      </script>');
   }
   else
   {
      $ReturnString = urlencode($ReturnString);
      echo('
      <script type="text/javascript">
         var $form = $("<form/>").attr("action", "'.$Act.'").attr("method", "post");
         $("body").append($form);
         AddParameter($form, "ReturnString", "'.$ReturnString.'")
         AddParameter($form, "AppID", "'.$AppID.'");
         $form[0].submit();
      </script>');
   }  
?>

Open in new window

Then, in the "action" file
<?
   if(isset($_REQUEST['Error']) && !empty($_REQUEST['Error'])){$Error = urldecode(json_decode($_REQUEST['Error']));}
   if(isset($_REQUEST['ReturnString']) && !empty($_REQUEST['ReturnString'])){$ReturnString = urldecode($_REQUEST['ReturnString']);}
   if(count($Error) > 0 || (isset($ReturnString) && !empty($ReturnString)))
   {
      echo('<script type="text/javascript">alert("');
      if(isset($ReturnString) && !empty($ReturnString))
      {
         echo($ReturnString."\n");
      }
      if(count($Error) > 0)
      {
         foreach($Error as $value)
         {
            echo($value."\n");
         }
      }
      echo('");</script>');
   }
?>

Open in new window

Avatar of Chris Stanyon
Chris Stanyon
Flag of United Kingdom of Great Britain and Northern Ireland image

The issue you have with the Unescaped linebreak is because you're not escaping the \n. You need the double slash:

echo($ReturnString."\\n");

The issue you face with expected expression %, is because you have the urldecode and json_decode the wrong way around. You're trying to json_decode a url_encoded string. You need to do it the other way around:

$Error = json_decode(urldecode($_REQUEST['Error']));

You seem to be jumping through a lot of hoops to get to where you want to go. You are using PHP to create a Javascript that creates a form and then submits it!

Would it not be easier, to write the info to the SESSION using PHP and then just redirect to your new page, where you can read in the session data directly:

session_start();

$_SESSION['AppID'] = $AppID;

if (count($Error)):
    $_SESSION['Error'] = $Error;
    unset($_SESSION['ReturnString']);
else:
    $_SESSION['ReturnString'] = $ReturnString;
    unset($_SESSION['Error']);
endif;

header("Location: {$Act}");

Open in new window

And then in your action page:

<?php
session_start();

$alert = "";

if ( isset($_SESSION['Error']) ):
    $alert = implode("\\n", $_SESSION['Error']);
elseif ( isset($_SESSION['ReturnString']) ):
    $alert = $_SESSION['ReturnString'];
endif;?>

<script>
    alert("<?= $alert ?>");
</script>

Open in new window

Avatar of RationalRabbit
RationalRabbit

ASKER

"The issue you have with the Unescaped linebreak is because you're not escaping the \n"
Sorry, that's not the issue, the error is referring to the sending script. As I stated, there are no line breaks written into the strings being sent. Below is the most complicated Return string message:
$ReturnString = "Record is now available in Customer Accounts and Pricing Admins Inboxes. Account Executive has been notified.";
"The issue you face with expected expression %, is because you have the urldecode and json_decode the wrong way"
I may have it wrong on the receiving end, but have tried it both ways.  Still receive errors. Keep in mind the error is occurring in the script where the form is created. At least, that us where the console is pointing to.
Curiously, why should there be an error anyway. It is just a quoted strung, no?
To reiterate, this is what a simple string may look like after encoding:
"%5B%22Source%3A+%22%5D"

If I reverse the encoding to json_encode(urlencode($Error)); I simply get a different Web console error:
SyntaxError: expected expression, got '<'
which, I assume, is the result of this PHP error:
<b>Warning</b>:  urlencode() expects parameter 1 to be string, array given
Usually, when this Web console produces an error, I understand what it is talking about and it provides a link that will take me to the proper line. In this case, it is not much help, other than recognizing there is an error.
"You seem to be jumping through a lot of hoops to get to where you want to go ..."
I recon that's an understatement :) The javascript alert code is something I already have on every page and is how I handle normal errors when one of these pages is called from a query string or an include is run. I've been using it for some time (4-5 years), on several sites, without a problem. The urlencode and json_encode I only added trying to get this to work. Usually, it detects a ReturnString or Error array on page load and executes.

These errors are so odd and puzzling to me that I kept tying other things, thinking there was something in the form creating JavaScript or something that was causing the changes. I was hoping maybe someone could see some stupid thing I was missing. I try to avoid using session globals, but I think you're right - I probably should have done that long ago.

I'll let you know how that works out.
Still, I hate puzzles without solutions.
OK. In your action page you have this:

echo('<script type="text/javascript">alert("');
      if(isset($ReturnString) && !empty($ReturnString))
      {
         echo($ReturnString."\n");
      }

Open in new window

That will generate the string literal contains an unescaped line break error because you're not escaping the \n. You need to escape it. It has nothing do do with the $Return string variable. It's because you're trying to add a \n to the end of it. It needs to be:

echo($ReturnString."\\n");

As for the other error, you've misread my previous comment. I'm not talking about the encoding in your first page - I'm talking about the decoding in the action page. In your first file you have this:

$js_Error = urlencode(json_encode($Error));

What you're doing here is json_encoding the $Error array and then urlencoding that JSON string. To get that info back in your action page, you need to do the opposite. You need to urldecode the value, and then JSON decode that string. You're doing that part the wrong way around. You have this:

$Error = urldecode(json_decode($_REQUEST['Error']))

That won't work - you're trying to json_decode the string first and then urldecode the result. You need to have:

$Error = json_decode(urldecode($_REQUEST['Error']))

Now it will urldecode the value, which will turn it back into a JSON string. Then you json_decode it to get the array.

As for avoiding using the SESSION ... why? HTTP is stateless, so you need a way to share info between pages, and using GET and POST all the time is just not practical nor efficient.
With all due respect, you're not listening. No need to double escape there.
Also, you said
"I'm not talking about the encoding in your first page"
I am because that us where the error is being produced. How do I know that? Because that  is where the debugger points to and it has not left that page when the error is produced.

Did you read my response?
Again, as I stated, "I may have it wrong on the receiving end ... Keep in mind the error is occurring in the script where the form is created."

Anyway, as I also stated, I will take your advice and just use session vars, which I have done, and it works fine, except that the idea of using header() is not an option. This is at the end of a file that accesses and writes to databases and send out emails using another script. So I still end up using JavaScript to relocate, with a little function I have in my PHP function library:
<?PHP
function Redirect($n)
{
   die("<script type=\"text/javascript\">window.location='$n';</script>");
}
?>

Open in new window

I've only had one situation where that did not work well, and simply added
<title>...</title></head><body></body></html>
after the </script> tag
It's simple, but it works in a pinch.

As for the receiving script bit, I didn't have to augment much. This is the actual code (the reason for the <br> replacement is that sometimes the message is used for more than one purpose, such as an HTML email message.:
<?PHP
   # =================================================== #
   #                M E S S A G E S                      #
   # =================================================== #
   if(!empty($_SESSION['Error'])){$Error = $_SESSION['Error']; unset($_SESSION['Error']);}
   if(!empty($_SESSION['Log'])){$Log = $_SESSION['Log']; unset($_SESSION['Log']);}
   if(!empty($_REQUEST['ReturnString'])){$ReturnString = $_REQUEST['ReturnString'];}
   if(count($Error) > 0 || isset($ReturnString))
   {
      echo('<script type="text/javascript">alert("');
      if(isset($ReturnString) && !empty($ReturnString))
      {
         $ReturnString = str_replace('<br />',' \n ',$ReturnString);
         echo($ReturnString . ' \n ');
      }
      if(count($Error) > 0)
      {
         foreach($Error as $value)
         {
            $String = str_replace('<br />',' \n ',$value);
            echo($String . ' \n ');
         }
      }
      echo('");');
      if(count($Log))
      {
         foreach($Log as $value)
         {
            echo('console.log("'.$value.'");');
         }
      }
      echo('
      </script>');
   }
?>

Open in new window

OK. I don't know what else to say. I tested your scripts and the errors all occured in the action page as I expected them to. If you're finding a different response, I can only presume something else must be going on with your code. Do you have a link to your page where I can take a look at it in action ??

FYI - you can still use the header() to redirect after db queries and emails as long as you haven't output any data, and as you're immediately submitting a form anyway, I can't see any reason why you would need to output anything.

Good luck with it.
ASKER CERTIFIED SOLUTION
Avatar of RationalRabbit
RationalRabbit

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks for your help, Chris.
No worries