using a textfield's text to update my db with a tweet - encoding issues with apostrophes

sstava 7 years ago updated by icahill (Administrator) 7 years ago 16
I have a need to update the text of a tweet in my app and make a JSON server call to store the updated tweet text on the server (parse.com).

Everything works fine until there is an apostrophe in the tweet text.

I have to use an eval with JSON.stringify to escape the quotes that could be in the tweet otherwise my JSON postContent to parse.com will be invalid.

The problem is that you have to use apostrophes to wrap the textfield value as the parameter to the JSON.stringify function call. When you use the apostrophes and their is an apostrophe in the text value of the textfield, you get an empty string for results.

I hope I am missing something obvious, but right now it seems like a catch-22 situation.

<texttemplate name="updateTweetTextTemplate"><![CDATA[
"requests": [
"method": "PUT",
"path": "/1/classes/tweet/[var:updatetweet-objectid]",
"body": { "tweet": [var:updatetweet-text] }
<assign property="var:updatetweet-objectid" value="_objectid" />
<assign property="var:updatetweet-text" value="[eval:JSON.stringify('[object:TWEET-TO-EDIT-ENTRY-_index.text]')]" />

<assign property="datasource:parseUpdateTweetText.postContent" value="[template:updateTweetTextTemplate.content]"/>

<assign property="datasource:parseUpdateTweetText.source" value="https://api.parse.com/1/batch"/>
If I understand correctly then you should be able to decodeURIComponent the object and then run it through the stringify.

<assign property="var:updatetweet-noapos" value="[eval:decodeURIComponent('[object:TWEET-TO-EDIT-ENTRY-_index.text]')]" />
<assign property="var:updatetweet-text" value="[eval:JSON.stringify('[var:updatetweet-noapos]')]" />
I think the problem still exits. If I use your reply to further the example...

Lets say that the value in object:TWEET-TO-EDIT-ENTRY-_index.text is:
--This is steve's example "text".--

Then the resolved eval looks something like:

[eval:decodeURIComponent('This is steve's example "text".')]

The apostrophe in the above string (i.e. steve's) will prematurely terminate the parameter being passed to decodeURIComponent because you are using apostrophes to contain the string/parameter and their is an apostrophe in the text.

Am I understanding that correctly?
Have you tried using the eval yet? The system should know the different between the wrapped apostrophe's and the one's inside the object. I know we are using this solution elsewhere, so if it isn't working please let me know and we can look at the code.
Yup. I had tried it in my app and it didn't work. I decided to remove it from the complexity and created an app called "testit" (you have access).

All it does is let you enter text in a textfield and then push a button that applies the decodeURIComponent and the JSON.stringify and pops an alert with the results. If you include an apostrophe in the textfield you get an empty string for a result. If you have quotes, but no apostrophes you get the appropriately escaped string as a result. Apostrophes seem to be the downfall :(
Okay, so I was thinking of this backwards, my apologies. This is what you need to do:

<assign property="var:updatetweet-noapos" encoding="url" value="[object:TEXT-ENTER.text]" />
I think apostrophes in a wire variable still cause an issue when trying to call a javascript function with that string as a parameter.

The use of any of the encoding options doesn't put the string in a state that will allow it to be successfully used as a parameter in a javascript function call. From what I am seeing, the apostrophe is never escaped.

There are two things contained in this comment:
1) Original issue: apostrophes still seem to terminate the wire variable string incorrectly when used in a javascript function call
2) Related issue: textfield text isn't in sync with onchange event

I changed the "testit" app to reflect my problem with apostrophes specific to my apps code.

In doing so, since fusebox v1.5 came out, I implemented my specific need. The specific need is taking the content of the textfield and passing it to a javascript function that determines the number of characters left for the tweet.

Originally, I was doing this on the save event of the screen in my app (apostrophes messed up the call to the character counting javascript function, otherwise it worked).
With the release of fusebox v1.5 I started using the onchange event for the textfield. I call the same javascript function; I can now check the length as the person types (Yay!).

In doing this test, I think I may have come across a bug with the onchange event. After you press the first key for the textfield, it calls the onchange action but the "text" property of the textfield is empty. When you press the second key, you get the content from the first key press, etc...

You can see both of these issues in the "testit" app.


Update your app to engine 1.5 in the platform settings and try again. The encoding features will only work on 1.5. 
Cool! That took care of my apostrophe problem (Yay!)

There still seems to be an issue with the onchange event and the text being one character behind when the text property is referenced in the onchange action.

You can see this in the "testit" app that I have in my account. You have access to it.


Your example wasn't taking advantage of the new count object property. 
I added this action to your example:

<action name="iancheckLength">
<assign property="object:CHAR-TEXT.text" value="[eval: 140 - [object:TEXT-ENTER.count]]" />
Cool! Good to know about the count property.

Regrettably, I can't use it to determine the available characters in a tweet.

A tweet's length is not just the sum if its characters. If there is a URL in the tweet you have to use the length of 22 even if the URL is greater or less than 22 characters. This is due to the t.co URL used for shortening a URL in a tweet. Twitter URL shortening is 22 characters for any http URL and 23 for any https URL.

I have copied the twitter-text.js into functions.html to enable the correct calculation

I still think the onchange might have an issue :)
Oh I see. In that case, I will have to test out a few more scenarios. Thanks!

I think I figured out the issue. Your var filler for your twitterCharsLeft js function started with a 0 and I suspect it was being ignored. I changed it to start with a 1 instead and I think that took care of it.

Try it out and let me know.
I took a look. The problem with the onchange event happens even if I don't call the twitterCharsLeft function.

I have changed the "testit" app to simply call an alert every time I type a character (onchange) in the textfield. The alert shows the content of the textfield.

The first time I type a character, the alert comes up empty. The second time I type a character, the alert comes up with the first character I typed, not the second one...and so on.

Is the expectation that the textfield.text property should have the most current character(s) in it when the onchange event fires?
Ok Steve, I haven't forgotten about this. I will take a look soon.
Not a problem. I appreciate the time you are spending to figure it out. If it would help to have me stop by some day when you have time, I would be happy to run through it with you.
Ok, I can confirm that this is a bug and I have logged a ticket for the issue. I will keep you posted.