# Logging Service API example

This section presents the full source code of a working sample widget for the Logging service. You can download the `wgz` package for this widget from section Example widgets.

For general information about creating widgets, see section Widget component files.

For widget development and debugging purposes, this example writes its output to `c:\data\jslog_widget.log` using `console.info`. For instructions on how to enable logging in the Web browser for S60, see section JavaScript console.

### Info.plist

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Nokia//DTD PLIST 1.0//EN" "http://www.nokia.com/NOKIA_COM_1/DTDs/plist-1.0.dtd">
    <plist version="1.0">
    <dict>
      <key>DisplayName</key>
    	 <string>LoggingSample</string>
    	 <key>Identifier</key>
      <string>com.nokia.widget.sapi.logging.sample</string>
      <key>Version</key>
      <string>1.0</string>
      <key>MainHTML</key>
      <string>logging-sample.html</string>
      <key>AllowNetworkAccess</key>
      <true/>
    </dict>
    </plist>

### Logging-sample.html

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <script type="text/javascript" src="js/common.js"></script>
        <script type="text/javascript" src="js/logging-sample.js"></script>
      </head>
      <body id='docBody' bgcolor="#ddeeff" onload="setup()" style=width:100%;height:100%;>

        <form name="frm">
        	<h3>Logging API Sample Widget</h3>

          <input type="button" onclick="addLog('img1')" value="AddLog"><img id="img1" src="pic/blank.png" width="25" height="25" align="center"><br>
          <input type="button" onclick="delLog('img2')" value="DeleteLog"><img id="img2" src="pic/blank.png" width="25" height="25" align="center"><br>
          <input type="button" onclick="getLogList('img3')" value="GetLogList"><img id="img3" src="pic/blank.png" width="25" height="25" align="center"><br>
          <input type="button" onclick="addLogAsync('img4')" value="AddLogAsync"><img id="img4" src="pic/blank.png" width="25" height="25" align="center"><br>
          <input type="button" onclick="delLogAsync('img5')" value="DeleteLogAsync"><img id="img5" src="pic/blank.png" width="25" height="25" align="center"><br>
          <input type="button" onclick="getLogListAsync('img6')" value="GetLogListAsync"><img id="img6" src="pic/blank.png" width="25" height="25" align="center"><br>
          <input type="button" onclick="requestNotification('img7')" value="RequestNotification"><img id="img7" src="pic/blank.png" width="25" height="25" align="center"><br>
          <input type="button" onclick="cancelAddLogAsync('img8')" value="CancelAddLogAsync"><img id="img8" src="pic/blank.png" width="25" height="25" align="center"><br>
          <input type="button" onclick="cancelDelLogAsync('img9')" value="CancelDeleteLogAsync"><img id="img9" src="pic/blank.png" width="25" height="25" align="center"><br>
          <input type="button" onclick="cancelGetLogListAsync('img10')" value="CancelGetLogListAsync"><img id="img10" src="pic/blank.png" width="25" height="25" align="center"><br>
          <input type="button" onclick="cancelRequestNotification('img11')" value="CancelRequestNotification"><img id="img11" src="pic/blank.png" width="25" height="25" align="center"><br>

    			<hr>
          <div class='loggingsample' id='loggingsample' bgcolor="#ddeeff" style=width:100%;height:100%;overflow:auto>
          </div>
        </form>
      </body>
    </html>

### common.js

    errCode = resultList.ErrorCode;
      var msg = "";

      if (errCode) {
        msg = message + "<BR>" + "Failed Error: " + errCode + "<BR>";
        if(resultList.ErrorMessage != undefined)
          msg += "Error Message: " + resultList.ErrorMessage;
        showIMG(imgId,"no");
      } else {
        showIMG(imgId,"yes");
      }

      //print error message
      if(divId != null && divId != undefined)
        document.getElementById(divId).innerHTML = msg;
      console.info(msg);

      return errCode;
    }

    // Build the message by reading an iterable list in a recursive manner
    function showIterableList(iterator)
    {
      var msg = "";
      try
      {
        iterator.reset();
        var item;
        while (( item = iterator.getNext()) != undefined ){
           msg += showObject( item );
        }
      }
      catch(e)
      {
        alert('<showIterableList> ' + e);
      }
      return msg;
    }

    // Build the message by reading a JS object in a recursive manner
    function showObject( obj )
    {
      var txt = "";
      try {
        if ( typeof obj != 'object' )
          return "" + obj + '<BR/>';
        else {
          for(var key in obj) {
            txt +=  key + ":";
            txt += showObject( obj[key] );
            txt += '<BR/>';
          }
          txt += '<BR/>';
        }
      }
      catch (e)
      {
        alert("showObject: " + e);
      }
      return txt;
    }

    // Show the image to indicate the test result
    function showIMG(imgId, isOK)
    {
      if(imgId == null || imgId == undefined)
        return;

      if(isOK == "yes")
        document.getElementById(imgId).src = "pic/yes.png";
      else if(isOK == "no")
        document.getElementById(imgId).src = "pic/no.png";
      else
        document.getElementById(imgId).src = "pic/blank.png";
    }

    // Show elements in object by using 'alert'
    function testObject(obj)
    {
      var msg = "";
      for(var key in obj) {
        msg = msg + ":" + key + "=" + obj[key];
      }
      alert(msg);
    }

    // Test whether the input is numeric
    function IsNumeric(sText)
    {
      var ValidChars = "0123456789.";
      var IsNumber=true;
      var Char;

      for (i = 0; i < sText.length && IsNumber == true; i++)
      {
        Char = sText.charAt(i);
        if (ValidChars.indexOf(Char) == -1)
        {
           IsNumber = false;
        }
      }
      return IsNumber;
    }

### Logging-sample.js

    // logging-sample.js
    //
    // In this sample a log event will be added, deleted, and listed. The notification will
    // be sent when the log changes.  Also, an async operation will be cancelled.
    //

    //SAPI Error Codes
    // 0  - Success
    // 1000 - InvalidServiceArgument
    // 1001 - UnknownArgumentName
    // 1002 - BadArgumentType
    // 1003 - MissingArgument
    // 1004 - ServiceNotSupported
    // 1005 - ServiceInUse
    // 1006 - ServiceNotReady
    // 1007 - NoMemory
    // 1008 - HardwareNotAvailable
    // 1009 - ServerBusy
    // 1010 - EntryExists
    // 1011 - AccessDenied
    // 1012 - NotFound
    // 1013 - UnknownFormat
    // 1014 - GeneralError
    // 1015 - CancelSuccess
    // 1016 - ServiceTimedOut
    // 1017 - PathNotFound

    // Declare the service object
    var so;

    // imgid for callback1 function
    var imgid_callback1;

    // imgid for callback2 function
    var imgid_callback2;

    // imgid for callback3 function
    var imgid_callback3;

    // imgid for callback4 function
    var imgid_callback4;

    // id of the div used to display information
    const DIV_ID = 'loggingsample';

    // Called from onload()
    function setup()
    {
      try {
        so = device.getServiceObject('Service.Logging', 'IDataSource');
        console.info("setup: so: %s", so);
      }
      catch (e) {
          alert('<setup> ' +e);
      }
    }

    // Add Log
    function addLog(imgId) {

      var itemMap = new Object();
      itemMap.EventType = 3; // ShortMessage event
      itemMap.RemoteParty = '16172333568';
      itemMap.PhoneNumber = '17819933882';
      itemMap.Direction = 1; // outgoing
      itemMap.Subject = 'Test txt msg';
      itemMap.Description = 'Hi, this is a text message to you';
      itemMap.DeliveryStatus = 1;  // Sent

      var criteria = new Object();
      criteria.Type = 'Log';
      criteria.Item = itemMap;

      try {
        var result = so.IDataSource.Add(criteria);
        checkError("IDataSource::Add",result,DIV_ID,imgId);
      }
      catch (e) {
        showIMG(imgId,"no");
        alert("addLog: " + e);
      }
    }

    // Delete Log
    function delLog(imgId) {

      // get "id" by using RequestNotification()
      var logId = prompt("Please enter the target log id", "");
      if (logId == "" || logId == null)
        return;

      var itemData = new Object();
      itemData.id = logId;

      var criteria = new Object();
      criteria.Type = 'Log';
      criteria.Data = itemData;

      try {
        var result = so.IDataSource.Delete(criteria);
        checkError("IDataSource::Delete",result,DIV_ID,imgId);
      }
      catch (e) {
        showIMG(imgId,"no");
        alert ("delLog: " + e);
      }
    }

    // Get the List of Log
    function getLogList(imgId) {

      var filterMap = new Object();
      filterMap.EventType = 3;// shortMessage event

      var criteria = new Object();
      criteria.Type = 'Log';
      criteria.Filter = filterMap;

      try {
        var result = so.IDataSource.GetList(criteria);
        if(!checkError("IDataSource::getLogList",result,DIV_ID,imgId)) {
          var msg = "";
          var obj;
          var it = result.ReturnValue;
          while ((obj = it.getNext()) != undefined) {
            msg = msg + "id: " + obj['id']+ "<br>";
            msg = msg + "EventType: " + obj['EventType'] + "<br>";
            msg = msg + "RemoteParty: " + obj['RemoteParty'] + "<br>";
            msg = msg + "PhoneNumber: " + obj['PhoneNumber'] + "<br>";
            msg = msg + "Subject: " + obj['Subject'] + "<br>";
            msg = msg + "Description: " + obj['Description'] + "<br>";
            msg = msg + "DeliveryStatus: " + obj['DeliveryStatus'] + "<br><br>";
          }
          it.reset();
          document.getElementById(DIV_ID).innerHTML = msg;
        }
      }
      catch (e) {
        showIMG(imgId,"no");
        alert ("getLogList: " + e);
      }
    }

    // Add Log Async
    function addLogAsync(imgId) {

      var itemMap = new Object();
      itemMap.EventType = 3; // ShortMessage event
      itemMap.RemoteParty = '16172333568';
      itemMap.PhoneNumber = '17819933882';
      itemMap.Direction = 1; // outgoing
      itemMap.Subject = 'Test txt msg';
      itemMap.Description = 'Hi, this is a text message to you';
      itemMap.DeliveryStatus = 1;  // Sent

      var criteria = new Object();
      criteria.Type = 'Log';
      criteria.Item = itemMap;

      // Set image id for callback1 function
      imgid_callback1 = imgId;

      try {
        var result = so.IDataSource.Add(criteria, callback1);
        if(!checkError("IDataSource::addLogAsync",result,DIV_ID,imgId)) {
          showIMG(imgId,"");
        }
      }
      catch (e) {
        showIMG(imgId,"no");
        alert ("addLogAsync: " + e);
      }
    }

    // Delete Log Async
    function delLogAsync(imgId) {

      // get "id" by using RequestNotification()
      var logId = prompt("Please enter the target log id", "");
      if (logId == "" || logId == null)
        return;

      var itemData = new Object();
      itemData.id = logId;

      var criteria = new Object();
      criteria.Type = 'Log';
      criteria.Data = itemData;

      // Set image id for callback2 function
      imgid_callback2 = imgId;

      try {
        var result = so.IDataSource.Delete(criteria, callback2);
        if(!checkError("IDataSource::delLogAsync",result,DIV_ID,imgId)) {
          showIMG(imgId,"");
        }
      }
      catch (e) {
        showIMG(imgId,"no");
        alert ("delLogAsync: " + e);
      }
    }

    // Get Log List Async
    function getLogListAsync(imgId) {

      var filterMap = new Object();
      filterMap.EventType = 3;

      var criteria = new Object();
      criteria.Type = 'Log';
      criteria.Filter = filterMap;

      // Set image id for callback3 function
      imgid_callback3 = imgId;

      try {
        var result = so.IDataSource.GetList(criteria, callback3);
        if(!checkError("IDataSource::getLogListAsync",result,DIV_ID,imgId)) {
          showIMG(imgId,"");
        }
      }
      catch (e) {
        showIMG(imgId,"no");
        alert ("getLogListAsync: " + e);
      }
    }

    // Cancel Add Log Async
    function cancelAddLogAsync(imgId) {

      var itemMap = new Object();
      itemMap.EventType = 3; // ShortMessage event
      itemMap.RemoteParty = '16172333568';
      itemMap.PhoneNumber = '17819933882';
      itemMap.Direction = 1; // outgoing
      itemMap.Subject = 'Test txt msg';
      itemMap.Description = 'Hi, this is a text message to you';
      itemMap.DeliveryStatus = 1;  // Sent

      var criteria = new Object();
      criteria.Type = 'Log';
      criteria.Item = itemMap;

      // Set image id for callback1 function
      imgid_callback1 = imgId;

      try {
        var result = so.IDataSource.Add(criteria, callback1);
        if(!checkError("IDataSource::cancelAddLogAsync",result,DIV_ID,imgId)) {
          showIMG(imgId,"");
          var criteria2 = new Object();
          criteria2.TransactionID = result.TransactionID;
          var result2 = so.IDataSource.Cancel(criteria2);
          checkError("IDataSource::cancelAddLogAsync",result2,DIV_ID,imgId);
        }
      }
      catch (e) {
        showIMG(imgId,"no");
        alert ("cancelAddLogAsync: " + e);
      }
    }

    // Cancel Delete Log Async
    function cancelDelLogAsync(imgId) {

      // get "id" by using RequestNotification()
      var logId = prompt("Please enter the target log id", "");
      if (logId == "" || logId == null)
        return;

      var itemData = new Object();
      itemData.id = logId;

      var criteria = new Object();
      criteria.Type = 'Log';
      criteria.Data = itemData;

      // Set image id for callback2 function
      imgid_callback2 = imgId;

      try {
        var result = so.IDataSource.Delete(criteria, callback2);
        if(!checkError("IDataSource::cancelDelLogAsync",result,DIV_ID,imgId)) {
          showIMG(imgId,"");
          var criteria2 = new Object();
          criteria2.TransactionID = result.TransactionID;
          var result2 = so.IDataSource.Cancel(criteria2);
          checkError("IDataSource::cancelDelLogAsync",result2,DIV_ID,imgId);
        }
      }
      catch (e) {
        showIMG(imgId,"no");
        alert ("cancelDelLogAsync: " + e);
      }
    }

    // Cancel Get Log List Async
    function cancelGetLogListAsync(imgId) {

      var filterMap = new Object();
      filterMap.EventType = 3;// shortMessage event

      var criteria = new Object();
      criteria.Type = 'Log';
      criteria.Filter = filterMap;

      // Set image id for callback3 function
      imgid_callback3 = imgId;

      try {
        var result = so.IDataSource.GetList(criteria, callback3);
        if(!checkError("IDataSource::cancelGetLogListAsync",result,DIV_ID,imgId)) {
          showIMG(imgId,"");
          var criteria2 = new Object();
          criteria2.TransactionID = result.TransactionID;
          var result2 = so.IDataSource.Cancel(criteria2);
          checkError("IDataSource::cancelGetLogListAsync",result2,DIV_ID,imgId);
        }
      }
      catch (e) {
        showIMG(imgId,"no");
        alert ("cancelGetLogListAsync: " + e);
      }
    }

    // Request Notification
    function requestNotification(imgId) {

      var filter = new Object();
      // The Minimum time, in Microseconds,
      // that elapses before the notification request can complete.
      filter.DelayTime = 2000000;

      var criteria = new Object();
      criteria.Type = 'Log';
      criteria.Filter = filter;

      // Set image id for callback4 function
      imgid_callback4 = imgId;

      try {
        var result = so.IDataSource.RequestNotification(criteria,callback4);
        checkError("IDataSource::requestNotification",result,DIV_ID,imgId);
      }
      catch (e) {
        showIMG(imgId,"no");
        alert ("requestNotification: " + e);
      }
    }

    // Cancel Request Notification
    function cancelRequestNotification(imgId) {

      var filter = new Object();
      // The Minimum time, in Microseconds,
      // that elapses before the notification request can complete.
      filter.DelayTime = 2000000;

      var criteria = new Object();
      criteria.Type = 'Log';
      criteria.Filter = filter;

      // Set image id for callback4 function
      imgid_callback4 = imgId;

      try {
        var result = so.IDataSource.RequestNotification(criteria,callback4);
        if(!checkError("IDataSource::cancelRequestNotification",result,DIV_ID,imgId)) {
          showIMG(imgId,"");
          var criteria2 = new Object();
          criteria2.TransactionID = result.TransactionID;
          var result2 = so.IDataSource.Cancel(criteria2);
          checkError("IDataSource::cancelRequestNotification",result2,DIV_ID,imgId);
        }
      }
      catch (e) {
        showIMG(imgId,"no");
        alert ("cancelRequestNotification: " + e);
      }
    }

    // This is the asynchronous callback handler
    function callback1(transId, eventCode, result)
    {
      console.info("addLogAsync: transId: %d  eventCode: %d result.ErrorCode: %d", transId, eventCode, result.ErrorCode);
      checkError("IDataSource::addLogAsync",result,DIV_ID,imgid_callback1);
    }

    // This is the asynchronous callback handler
    function callback2(transId, eventCode, result)
    {
      console.info("delLogAsync: transId: %d  eventCode: %d result.ErrorCode: %d", transId, eventCode, result.ErrorCode);
      checkError("IDataSource::delLogAsync",result,DIV_ID,imgid_callback2);
    }

    // This is the asynchronous callback handler
    function callback3(transId, eventCode, result)
    {
      console.info("getLogListAsync: transId: %d  eventCode: %d result.ErrorCode: %d", transId, eventCode, result.ErrorCode);
      if(!checkError("IDataSource::getLogListAsync",result,DIV_ID,imgid_callback3)) {
        var msg = "";
        var obj;
        var meetingIt = result.ReturnValue;
        while ((obj = meetingIt.getNext()) != undefined) {
          msg = msg + "id: " + obj['id']+ "<br>";
          msg = msg + "EventType: " + obj['EventType'] + "<br>";
          msg = msg + "RemoteParty: " + obj['RemoteParty'] + "<br>";
          msg = msg + "PhoneNumber: " + obj['PhoneNumber'] + "<br>";
          msg = msg + "Subject: " + obj['Subject'] + "<br>";
          msg = msg + "Description: " + obj['Description'] + "<br>";
          msg = msg + "DeliveryStatus: " + obj['DeliveryStatus'] +"<br><br>";
        }
        meetingIt.reset();
        document.getElementById(DIV_ID).innerHTML = msg;
      }
    }

    // This is the asynchronous callback handler
    function callback4(transId, eventCode, result)
    {
      console.info("getLogListAsync: transId: %d  eventCode: %d result.ErrorCode: %d", transId, eventCode, result.ErrorCode);
      if(!checkError("IDataSource::RequestNotificationAsync",result,DIV_ID,imgid_callback4)) {
        document.getElementById(DIV_ID).innerHTML = showObject("Event Log has been updated!");
      }
    }