Service Portal consoleError
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎01-18-2018 11:02 AM
I m getting this error in the console while trying to access the catalog item in the service portal. This occurs in PRD environment but works fine in stage/TEST/Dev
amb.MessageClient [INFO] >>> connection exists, request satisfied
js_includes_sp.jsx?v=02-24-2017_1059&lp=Fri_Oct_06_20_23_58_PDT_2017&c=33_354:11973 TypeError: Cannot read property 'description' of undefined
This is the line
$scope.data.sc_cat_item.description = $sce.trustAsHtml($scope.data.sc_cat_item.description);

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎01-18-2018 11:09 AM
Can you post the server script, html and client controller script?
Please mark this response as correct or helpful if it assisted you with your question.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎01-18-2018 11:20 AM
Html:(There is an extra div at the end. but thats not a prob i guess. i just removed and verified it.. it doesnt make differennce
<div id="sc_cat_item" >
<div class="row" ng-if="::data.sc_cat_item" >
<div ng-if="::data.sc_cat_item.picture" class="col-sm-3">
<div class="panel panel-{{::options.color}} b wrapper-lg text-center">
<img class="img-responsive catalog-item-image" style="display: inline" ng-src="{{::data.sc_cat_item.picture}}" />
</div>
</div>
<div ng-class="{true:'col-sm-9',false:'col-sm-12'}[data.sc_cat_item.picture.length > 0]">
<div class="panel panel-default">
<div class="wrapper-md">
<h1 class="h2 m-t-none m-b-sm font-thin">{{::data.sc_cat_item.name}}</h1>
<div class="text-muted">{{::data.sc_cat_item.short_description}}</div>
</div>
<div ng-if="::data.sc_cat_item.description" class="wrapper-md b-t">
<div ng-bind-html="::data.sc_cat_item.description"></div>
</div>
<div ng-if="::data.sc_cat_item.content_type == 'external'" class="wrapper-md"><a ng-href="{{::data.sc_cat_item.url}}" target={{::data.sc_cat_item.target}}>{{::data.sc_cat_item.url}} âžš</a></div>
<div ng-if="::data.sc_cat_item.content_type == 'kb'" class="wrapper-md"><a ng-href="?id=kb_article&sys_id={{::data.sc_cat_item.kb_article}}">${Go to KB Article:} {{::data.sc_cat_item.kb_article_description}}</a></div>
<div ng-if="::data.sc_cat_item._fields">
<sp-cat-item item="::data.sc_cat_item" />
<form>
<div ng-class="{'b-t wrapper-md': data.sc_cat_item._view.length}">
<!-- display view and model -->
<sp-model form-model="::data.sc_cat_item" mandatory="mandatory"></sp-model>
</div>
<div ng-if="data.sc_cat_item.sys_class_name != 'sc_cat_item_content'" class="b-t wrapper-md">
<div class="m-b" ng-if="data.showPrices && (data.sc_cat_item.price || data.sc_cat_item.recurring_price)" >
<h4 ng-if="data.sc_cat_item.price" class="cat_item_price">${Price}: {{data.sc_cat_item.price}}</h4>
<em ng-if="data.sc_cat_item.recurring_price" class="cat_item_price">${Recurring Price}: {{data.sc_cat_item.recurring_price}}</em>
</div>
<now-attachments-list template="sp_attachment_single_line" ></now-attachments-list>
<select ng-if="c.showQuantitySelector()"
ng-disabled="submitted"
class="form-control quantity-selector"
ng-model="c.quantity"
ng-options="num for num in [1,2,3,4,5,6,7,8,9,10]">
</select>
<!--<button type="button" ng-click='c.saveMe('$[sysparm_id]','Template')' id="save-as-template">Save as Draft</button>-->
<button tabindex="0" name="submit" ng-disabled="submitted" ng-click="triggerOnSubmit()" class="btn btn-primary">{{submitButtonMsg}}</button>
<!-- <button tabindex="0" ng-if="c.showAddCartBtn()" name="submit" ng-disabled="submitted" ng-click="triggerAddToCart()" class="btn btn-default">${Add to Cart}</button> -->
<span ng-if="submitting" style="padding-left:4px">${Submitting...}</span>
<label tabindex="0" ng-if="!submitted" style="float:right;font-weight:normal;cursor:pointer;">
<!--<sp-attachment-button></sp-attachment-button><span style="padding-left:4px;">${Add attachments}</span>--></label>
<!-- <div ng-if="hasMandatory(mandatory)" class="alert alert-info" style="margin-top: .5em">
<span ng-if="hasMandatory(mandatory)">${Required information} </span> -->
<!--<span ng-repeat="f in mandatory" class="label label-danger" style="margin-right: .5em; display: inline-block;">{{::f.label}}</span>-->
<!-- </div> -->
</div>
</form>
</div>
</div>
</div>
</div>
<sp-message-dialog name="delete_attachment"
title="{{m.dialogTitle}}"
message="{{m.dialogMessage}}"
ok="{{m.dialogOK}}"
cancel="{{m.dialogCancel}}"
dialog-class="delete-dialog"/>
<div ng-if="::!data.sc_cat_item" >
<div class="panel panel-default" ng-if="::data.sys_id">
<div class="panel-heading"><h4 class="panel-title">${Item not found: {{::data.sys_id}}}</h4></div>
<!--<div class="panel-body wrapper">-->
<p>${This item is not found or currently not available}</p>
<p>${Suggestions}:</p>
<ul>
<li>${Try searching for the item}</li>
<li>${Go to the Service Catalog homepage}</li>
<li>${Contact your portal administrator}</li>
</ul>
</div>
</div>
</div>
<div>
</div>
</div>
Server Script
/
/ populate the 'data' variable with catalog item, variables, and variable view
(function() {
options.show_add_cart_button = (options.show_add_cart_button == "false");
if (options.page) {
var pageGR = new GlideRecord("sp_page");
options.page = (pageGR.get(options.page)) ? pageGR.getValue("id") : null;
}
if (options.table) {
var tableGR = new GlideRecord("sys_db_object");
options.table = (tableGR.get(options.table)) ? tableGR.getValue("name") : null;
}
options.url = options.url || "?id={page}&table={table}&sys_id={sys_id}";
data.showPrices = $sp.showCatalogPrices();
var m = data.msgs = {};
m.submitMsg = gs.getMessage("Submit");
m.submittedMsg = gs.getMessage("Submitted");
m.createdMsg = gs.getMessage("Created");
m.trackMsg = gs.getMessage("track using 'Requests' in the header or");
m.clickMsg = gs.getMessage("click here to view");
//m.dialogTitle = gs.getMessage("Delete Attachment");
m.dialogMessage = gs.getMessage("Are you sure?");
m.dialogOK = gs.getMessage("OK");
m.dialogCancel = gs.getMessage("Cancel");
//m.largeAttachmentMsg = gs.getMessage("Attached files must be smaller than {0} - please try again", "24MB");
/*if (input)
data.sys_id = input.sys_id;
else if(options.sys_id)
data.sys_id = options.sys_id;
else
data.sys_id = $sp.getParameter("sys_id") || $sp.getParameter('sl_sys_id');*/
data.sys_id="7eab63034f30070031f9f7e18110c79e"; //"87aa36c6db48c700fdefff971d9619ee";
//data._attachmentGUID = gs.generateGUID();
// portal can specify a catalog home page
data.sc_catalog_page = $sp.getDisplayValue("sc_catalog_page") || "sc_home";
var validatedItem = new GlideappCatalogItem.get(data.sys_id);
if (!validatedItem.canView())
return;
data.sc_cat_item = $sp.getCatalogItem(data.sys_id,true);
if (data.sc_cat_item.category) {
var categoryGR = new GlideRecord('sc_category');
categoryGR.get(data.sc_cat_item.category);
data.category = {
name: categoryGR.getDisplayValue('title'),
url: '?id=sc_category&sys_id=' + categoryGR.sys_id
};
}
$sp.logStat('Catalog View', data.sc_cat_item.sys_class_name, data.sys_id, data.sc_cat_item.name);
})();
Client Controller:
function ($scope, $http, spUtil, nowAttachmentHandler, $rootScope, $sanitize, $window, $sce, i18n) {
var c = this;
c.quantity = 1;
$scope.data.sc_cat_item.description = $sce.trustAsHtml($scope.data.sc_cat_item.description);
c.widget._debugContextMenu = [
[ i18n.getMessage("Open") + " sc_cat_item", function(){
var item = c.data.sc_cat_item;
$window.open("/$sp.do?id=form&table=" + item.table + "&sys_id=" + item.sys_id); }]
];
// c.showAddCartBtn = function() {
// return c.options.show_add_cart_button &&
// c.data.sc_cat_item.sys_class_name !== "sc_cat_item_producer" &&
// !c.data.sc_cat_item.no_cart;
// };
c.showQuantitySelector = function() {
return c.data.sc_cat_item.sys_class_name !== "sc_cat_item_producer" &&
!c.data.sc_cat_item.no_quantity;
};
$scope.$on('dialog.upload_too_large.show', function(e){
console.log($scope.m.largeAttachmentMsg);
spUtil.addErrorMessage($scope.m.largeAttachmentMsg);
});
$scope.m = $scope.data.msgs;
$scope.submitButtonMsg = $scope.m.submitMsg;
var ah = $scope.attachmentHandler = new nowAttachmentHandler(setAttachments, function() {});
ah.setParams('sp_portal', $scope.data._attachmentGUID, 1024 * 1024 * 24);
function setAttachments(attachments, action) {
$scope.attachments = attachments;
}
$scope.attachmentHandler.getAttachmentList();
$scope.confirmDeleteAttachment = function(attachment, $event) {
$rootScope.$broadcast("dialog.delete_attachment.show", {
parms: {
ok: function() {
$scope.attachmentHandler.deleteAttachment(attachment);
$rootScope.$broadcast("dialog.delete_attachment.close");
},
cancel: function() {
$rootScope.$broadcast("dialog.delete_attachment.close");
},
details: attachment.name
}
});
};
// Breadcrumbs
if ($scope.data.sc_cat_item) {
var bc = [{label: $scope.page.title, url: '?id=' + $scope.data.sc_catalog_page}];
if ($scope.data.category)
bc[bc.length] = {label: $scope.data.category.name, url: $scope.data.category.url};
bc[bc.length] = {label: $scope.data.sc_cat_item.name, url: '#'};
$rootScope.$broadcast('sp.update.breadcrumbs', bc);
spUtil.setSearchPage('sc');
}
var g_form;
$scope.$on('spModel.gForm.initialized', function(e, gFormInstance){
g_form = gFormInstance;
// This runs after all onSubmit scripts have executed
g_form.$private.events.on('submitted', function(){
if ($scope.data.sc_cat_item.item_action === "order")
getOne();
else if ($scope.data.sc_cat_item.item_action === "add_to_cart")
addToCart();
});
});
// $scope.triggerAddToCart = function() {
// $scope.data.sc_cat_item.item_action = "add_to_cart";
// $scope.data.sc_cat_item.quantity = c.quantity;
// if (g_form)
// g_form.submit();
// };
$scope.triggerOnSubmit = function(){
$scope.data.sc_cat_item.item_action = "order";
$scope.data.sc_cat_item.quantity = c.quantity;
if (g_form)
g_form.submit();
};
// order / create request
function getOne() {
postCatalogFormRequest().success(function(response) {
var a = response.answer;
var n = a.number;
$scope.$emit("$$uiNotification", response.$$uiNotification);
$scope.$emit("$sp.sc_cat_item.submitted", a);
if (n)
issueMessage(n, a.table, a.sys_id);
$scope.submitting = false;
$scope.submitButtonMsg = $scope.m.submittedMsg;
});
}
// function addToCart() {
// postCatalogFormRequest().success(function(response) {
// $rootScope.$broadcast("$sp.service_catalog.cart.add_item");
// $rootScope.$broadcast("$sp.service_catalog.cart.update");
// //spUtil.addInfoMessage("Added item to shopping cart");
// $scope.submitting = false;
// });
// }
function postCatalogFormRequest() {
setFieldsReadonly();
$scope.submitted = true;
$scope.submitting = true;
var t = $scope.data.sc_cat_item;
t._attachmentGUID = $scope.data._attachmentGUID;
// calls into SPCatalogForm.getItem()
return $http.post(spUtil.getURL('sc_cat_item'), t);
}
// spModel populates mandatory - hasMandatory is called by the submit button
$scope.hasMandatory = function(mandatory) {
return mandatory && mandatory.length > 0;
};
// switch catalog items
var unregister = $scope.$on('$sp.list.click', onListClick);
$scope.$on("$destroy", function() {
unregister();
});
function onListClick(evt, arg) {
$scope.data.sys_id = arg.sys_id;
spUtil.update($scope);
}
function setFieldsReadonly(){
var allFields = g_form.getFieldNames();
for(var fieldName in allFields){
g_form.setReadOnly(allFields[fieldName], true);
}
}
function issueMessage(n, table, sys_id) {
var page = table == 'sc_request' ? 'sc_request' : 'ticket';
if (c.options.page) {page = c.options.page;}
if (c.options.table) {table = c.options.table;}
var url = spUtil.format(c.options.url, {page: page, table: table, sys_id: sys_id});
if (c.options.auto_redirect == "true") {
$window.location.href = url;
return;
}
var t = $scope.m.createdMsg + " " + n + " - ";
t += $scope.m.trackMsg;
t += ' <a href="' + url + '">' + $scope.m.clickMsg + '</a>';
spUtil.addInfoMessage(t);
}
}
function saveMe(){
var c = this;
c.saveMe = function(){
alert("working");
if(type == 'Template'){
//if type is template, call dialog window (UI Page)
var dialog = new GlideDialogWindow("u_catalog_template_name");
dialog.setTitle("Create Template"); //Set the dialog title
dialog.render(); //Open the dialog
//UI Page (u_catalog_template_name) has client script that calls 'finishProcess' function below
}
else{
//if type is Draft, process this request
finishProcess(catItem,type);
}
};
c.finishProcess = function(catItem,type){
alert('made it');
//during processing, show loading window
showLoadingDialog();
//call script include to gather variables assocaited with this catalog item
var ga = new GlideAjax('global.u_catalogAjaxHelper');
ga.addParam('sysparm_name','saveAsDraft');
ga.addParam('sysparm_catItem',catItem);
ga.getXMLAnswer(
function (response_in) {
//response_in will be an array of variable names
var variableList = response_in.split(',');
//create an object to use to build JSON string
var jsonObj = {};
/*
for each variable, create a new variable in the Object. Only want to pull 'draft_unique_id' if this is a draft
*/
for(i=0;i<variableList.length;i++){
if(type == 'Draft' || (type == 'Template' && variableList[i] != 'draft_unique_id')){
jsonObj[variableList[i]] = g_form.getValue(variableList[i]);
}
}
//convert jsonStr to a string so we can pass back to the server
var jsonStr = JSON.stringify(jsonObj);
/*
Need to use the json String to push off to a new 'Catalog Item Drafts' record (or update existing)
*/
var ga2 = new GlideAjax('global.u_catalogAjaxHelper');
ga2.addParam('sysparm_name','pushToDraft');
ga2.addParam('sysparm_draftType',type);//Draft or Template
ga2.addParam('sysparm_catItem',catItem);//sys_id of catalog item
ga2.addParam('sysparm_jsonStr',jsonStr);//object
ga2.addParam('sysparm_uniqueId',g_form.getValue('draft_unique_id'));//unique ID
ga2.addParam('sysparm_templateName',templateNameGlobal);//global variable set up by onLoad client script. will hold value of template name if this is a template being used
ga2.getXMLAnswer(
function(response_in2){
hideLoadingDialog();
alert(response_in2);
});
});
}
}

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎01-18-2018 12:09 PM
Do you have description for every Catalog Item?
Can you modify the Client Control script to
if ($scope.data.sc_cat_item.description)
$scope.data.sc_cat_item.description = $sce.trustAsHtml($scope.data.sc_cat_item.description);
Please mark this response as correct or helpful if it assisted you with your question.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎01-18-2018 12:14 PM
Hi sanjivmeher
Again i m getting the same error in the console
js_includes_sp.jsx?v=02-24-2017_1059&lp=Fri_Oct_06_20_23_58_PDT_2017&c=33_354:11973 TypeError: Cannot read property 'description' of undefined
at api.controller (euts-cat-item-soft-intake-form.js:5)