Emoji retrieved in JSON break Client Script?

Jean-Lou
Giga Guru

Hello, 

 

With my client I have created a UI action to create a Problem from incident, 

The UI action cannot submit the problem directly but must open a New problem record prefilled with the value retrieved from the INC. 

 

To do so I created the following known mechanic with GlideAjax - Client Script and Script Include to make the information available from Server side or Client side. 

 

Last part was to create an Async BR to link the new problem if the user decided to submit it with the original incident. 

 

This is working really well, but during the testing phase, we detected that if some emojis were added in the incident Description, Everything seems to break and the UI Action open the new form but nothing is prefilled properly. 

 

Using info message on the client script, I notice that it seems to break when calling the GlideAjax and Script Include, I suppose this is the JSON that is 'broken' and everything stop. 

 

However, I retested all my scripts on a PDI and I don't have the same behavior, The Emojis are correctly passed to the JSON and appears on my new record. and the description field is the same type on the PDI or the client instance 'String' but not UTF8; I though that would be the issue but without it, on the PDI it is ok?!

 

If Anyone would have an idea how to solve this ? Thank a lot in advance. 

Below the used scripts : 

 

 

UI Action "Create PRB": To redirect on a new PRB form with a custom sysparm = the original Incident sys_id

----------------------------------------------

var incSysID = current.getUniqueValue();
 
var url = 'problem.do?sys_id=-1&sysparm_custom=' + incSysID;

action.setRedirectURL(url);
action.setReturnURL(current);

-----------------------------------------------

Then an onLoad Client Script with GlideAjax method calling a Script include to set the Value on the new form based on the sysid value of the custom sysparm. 

I had to set a tiny sleep time at the start of the client script to be sure that the redirection is finished before launching the script. 

-----------------------------------------------------------------

function onLoad() {
function sleep (time) {
    return new Promise((resolve) => setTimeout(resolve, time));
  }
  sleep(1000).then(() => {
    if (g_form.isNewRecord()) {
        var incSysID = getParameterValue('sysparm_custom');
 
        if (incSysID) {
            var ga = new GlideAjax('GetIncidentDetails');
            ga.addParam('sysparm_name', 'getIncidentDetails');
            ga.addParam('sysparm_inc_sys_id', incSysID);
            ga.getXMLAnswer(function (answer) {
                var incDetails = JSON.parse(answer);
 
                if (!incDetails.error) {
                    g_form.setValue('parent', incSysID);
                    g_form.setValue('description', incDetails.description);
                    g_form.setValue('short_description', incDetails.short_description);
                    g_form.setValue('cmdb_ci', incDetails.cmdb_ci);
                    g_form.setValue('u_source', 'Internal Incident');
                    g_form.setValue('u_internal', true);
 
 
                    if (incDetails.u_internal == false) {
                        g_form.setValue('u_source', 'Incident');
                        g_form.setValue('u_internal', false);
                        g_form.setValue('company', incDetails.company);
                        g_form.setValue('business_service', incDetails.business_service);
                        g_form.setValue('service_offering', incDetails.service_offering);
                    }
 
                } else {
                    alert('error ' + incDetails.error);
                }
            });
        }
    }
  });
}
  
function getParameterValue(paramName) {
 
    var url = top.location.href;
    var decodedURL = decodeURIComponent(url);
    var value = new URLSearchParams(decodedURL).get(paramName);
 
    if (value) {
        return value;
    }
    if (!value) {
        var gUrl = new GlideURL();
        gUrl.setFromCurrent();
        value = gUrl.getParam("sysparm_id");
        return value;
    }
}

-------------------------------------------------------------------------

 

Script Include used to generate a JSON with the INC value that will be used to fill the new form : 

----------------------------------------------------------------

var GetIncidentDetails = Class.create();
GetIncidentDetails.prototype = Object.extendsObject(AbstractAjaxProcessor, {
    getIncidentDetails: function() {
        var incSysID = this.getParameter('sysparm_inc_sys_id');
        var incidentGR = new GlideRecord('incident');

        incidentGR.addQuery('sys_id', incSysID);
        incidentGR.query();

        if (incidentGR.next()) {
            var isInternal = new global.FilterWS().isInternal(incidentGR);
           
            var incDetails = {
                sys_id: incidentGR.getUniqueValue(),
                number: incidentGR.getValue('number'),
                description: incidentGR.getValue('description'),
                short_description: incidentGR.getValue('short_description'),
                cmdbci: incidentGR.getValue('cmdb_ci'),
                u_internal: isInternal,
            };

            if(isInternal == false) {

                incDetails.company = incidentGR.getValue('company');
                incDetails.business_service = incidentGR.getValue('business_service');
                incDetails.service_offering = incidentGR.getValue('service_offering');
            }
            return JSON.stringify(incDetails);
        } else {
            return JSON.stringify({
                error: 'Incident not found'
            });
        }
    },
    type: 'GetIncidentDetails'
});

 

***********************************

 

 

1 ACCEPTED SOLUTION

Tushar
Kilo Sage
Kilo Sage

Hi @Jean-Lou 

 

I think the issue you're facing with emojis breaking the process might be related to character encoding or how the data is handled during JSON serialization.

Can you please double check that you are using the same character encoding? Emojis may involve special characters, and consistency in encoding is crucial.

While GlideAjax usually handles encoding for you, using encodeURIComponent can provide an extra layer of safety for complex data.

 

Please, don't forget to mark my answer as correct if it solves your issue or mark it as helpful if it is relevant for you!

Regards,
Tushar

 

View solution in original post

3 REPLIES 3

Tushar
Kilo Sage
Kilo Sage

Hi @Jean-Lou 

 

I think the issue you're facing with emojis breaking the process might be related to character encoding or how the data is handled during JSON serialization.

Can you please double check that you are using the same character encoding? Emojis may involve special characters, and consistency in encoding is crucial.

While GlideAjax usually handles encoding for you, using encodeURIComponent can provide an extra layer of safety for complex data.

 

Please, don't forget to mark my answer as correct if it solves your issue or mark it as helpful if it is relevant for you!

Regards,
Tushar

 

Hi Tushar, 

 

Thanks for taking the time to answer, This did the trick. 

 

I added EncodeURIComponent on the creation of the object only for the Description field. 

And used DecodeURIComponent when setting the form value. 

 

Perfect Thanks 

Thanks Tushar for taking the time to answer. 

 

this did the trick : 

 

in the Script include when creating the JSON : 

 

var desc = encodeURIComponent(incidentGR.description);

var incDetails = {
sys_id: incidentGR.getUniqueValue(),
number: incidentGR.getValue('number'),
description: desc,
short_description: incidentGR.getValue('short_description'),
cmdbci: incidentGR.getValue('cmdb_ci'),
u_internal: isInternal,
};

And Client Script when setting the values : 

 

g_form.setValue('description', decodeURIComponent(incDetails.description));

 

Thanks a lot