Landmarks Service API example

This section presents the full source code of a working sample widget for the Landmarks Service. You can download the wgz package for this widget from section Introduction to STEW.

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

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>LandmarksSample</string>
    <key>Identifier</key>
    <string>com.nokia.widget.sapi.landmarks.sample</string>
    <key>Version</key>
    <string>1.0</string>
    <key>MainHTML</key>
    <string>landmarks-sample.html</string>
</dict>
</plist>

landmarks-sample.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <script type="text/javascript" src="js/landmarks-sample.js" charset="utf-8"></script>
    <script type="text/javascript" src="js/common.js" charset="utf-8"></script>
</head>
<body onload='setup()' bgcolor="#ddeeff">
    <form>
        <h3>Landmarks Service API Sample Widget</h3>
        <input type="button" onclick="addCategory('img1');" value="AddCategory"><img id="img1" src="pic/blank.png" width="25" height="25" align="center"><br>
        <input type="button" onclick="addLandmark('img2')" value="AddLandmark"><img id="img2" src="pic/blank.png" width="25" height="25" align="center"><br>
        <input type="button" onclick="getListDatabases('img3')" value="GetListDatabases"><img id="img3" src="pic/blank.png" width="25" height="25" align="center"><br>
        <input type="button" onclick="getListCategories('img4')" value="GetListCategoriesSync"><img id="img4" src="pic/blank.png" width="25" height="25" align="center"><br>
        <input type="button" onclick="getListCategoriesAsync('img5')" value="GetListCategoriesAsync"><img id="img5" src="pic/blank.png" width="25" height="25" align="center"><br>
        <input type="button" onclick="getListLandmarks('img6')" value="GetListLandmarksSync"><img id="img6" src="pic/blank.png" width="25" height="25" align="center"><br>
        <input type="button" onclick="getListLandmarksAsync('img7')" value="GetListLandmarksAsync"><img id="img7" src="pic/blank.png" width="25" height="25" align="center"><br>
        <input type="button" onclick="cancelCategoriesAsync('img8')" value="CancelCategoriesAsync"><img id="img8" src="pic/blank.png" width="25" height="25" align="center"><br>
        <input type="button" onclick="cancelLandmarksAsync('img9')" value="CancelLandmarksAsync"><img id="img9" src="pic/blank.png" width="25" height="25" align="center"><br>
        <input type="button" onclick="deleteCategory('img10')" value="DeleteCategory"><img id="img10" src="pic/blank.png" width="25" height="25" align="center"><br>
        <input type="button" onclick="deleteLandmark('img11')" value="DeleteLandMark"><img id="img11" src="pic/blank.png" width="25" height="25" align="center"><br>
        <input type="button" onclick="exportLandmarks('img12')" value="ExportLandmarks"><img id="img12" src="pic/blank.png" width="25" height="25" align="center"><br>
        <input type="button" onclick="importLandmarks('img13')" value="ImportLandmarks"><img id="img13" src="pic/blank.png" width="25" height="25" align="center"><br>
        <input type="button" onclick="organiseLandmarks('img14')" value="OrganiseLandmarks"><img id="img14" src="pic/blank.png" width="25" height="25" align="center"><hr>
        <div class='landmarks' id='landmarks' bgcolor="#ddeeff" style=width:100%;height:100%;overflow:auto>
        </div>
    </form>
</body>
</html>

common.js

// common.js
//
// This file contains some utility functions

// Check the error code and show the information to users
function checkError(message, resultList, divId, imgId)
{
  var 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 a iteratorable 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;
}

landmarks-sample.js

// landmarks-sample.js
//
// In this sample Categories will be added, deleted, and listed from default database,
// Landmarks will be imported, exported, added, deleted, and listed from sample database
// Also, async operation will be canceled

//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;

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

// imgid for callback1 function
var imgid_callback1;

// imgid for callback2 function
var imgid_callback2;

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

// Add new Category
// Note: Category with the CategoryName can not be added twice.
// So, you should delete just added category first and add category after that
function addCategory(imgId)
{
  // Setup input params using dot syntax
  var category = new Object();
  category.CategoryName = 'MyCategory';
  var criteria = new Object();
  criteria.Type = 'Category';
  criteria.Data = category;
  try
  {
    var resultList = so.IDataSource.Add(criteria);
    checkError("IDataSource::addCategory",resultList,DIV_ID,imgId);
  }
  catch(e)
  {
    showIMG(imgId,"no");
    alert ("addCategory: " + e);
  }
}

// Populate a Landmark Object with sample data
function populateLandmark(landmark)
{
  var landmarkfields = new Object();
  landmarkfields.Country = 'USA';
  landmarkfields.AreaCode = '01803';
  landmarkfields.City = 'Boston';
  landmarkfields.District = 'Dist';
  landmarkfields.Street = 'Wayside Rd';
  landmarkfields.Telephone = '781-993-9393';

  landmark.DatabaseURI      = 'file://c:eposlm.ldb';
  landmark.LandmarkName     = 'NewLandmark';
  landmark.LandmarkDesc     = 'My Landmark';
  landmark.LandmarkFields   = landmarkfields;
}

// Add new Landmark (sync operation)
function addLandmark(imgId)
{
  // Setup input params using dot syntax
  var criteria = new Object();
  criteria.Type = 'Landmark';

  try
  {
    var lm = so.IDataSource.New( criteria );
    populateLandmark(lm);
    var criteria1 = new Object();
    criteria1.Type = 'Landmark';
    criteria1.Data = lm;
    var resultList = so.IDataSource.Add(criteria1);
    checkError("IDataSource::addLandmark",resultList,DIV_ID,imgId);
  }
  catch(e)
  {
    showIMG(imgId,"no");
    alert ("addLandmark: " + e);
  }
}


// Get List of all Databases (sync operation)
function getListDatabases(imgId)
{
  // Setup input params using dot syntax
  var criteria = new Object();
  criteria.Type = 'Database';
  try
  {
    var resultList = so.IDataSource.GetList(criteria);
    if(!checkError("IDataSource::getListDatabases",resultList,DIV_ID,imgId)) {
      document.getElementById(DIV_ID).innerHTML = showIterableList(resultList.ReturnValue);
    }
  }
  catch(e)
  {
    showIMG(imgId,"no");
    alert ("getListDatabases: " + e);
  }
}

// Get List of all Categories (sync operation)
function getListCategories(imgId)
{
  // Setup input params using dot syntax
  var criteria = new Object();
  criteria.Type = 'Category';
  try
  {
    var resultList = so.IDataSource.GetList(criteria);
    if(!checkError("IDataSource::getListCategories",resultList,DIV_ID,imgId)) {
      document.getElementById(DIV_ID).innerHTML = showIterableList(resultList.ReturnValue);
    }
  }
  catch(e)
  {
    showIMG(imgId,"no");
    alert ("getListCategories: " + e);
  }
}

// Get List of all Categories (Async operation)
function getListCategoriesAsync(imgId)
{
  // Setup input params using dot syntax
  var criteria = new Object();
  criteria.Type = 'Category';
  try
  {
    imgid_callback1 = imgId;
    var resultList = so.IDataSource.GetList(criteria, callback1);
    if(!checkError("IDataSource::getListCategoriesAsync",resultList,DIV_ID,imgId))
      showIMG(imgId, "");
  }
  catch(e)
  {
    showIMG(imgId,"no");
    alert ("addCategory: " + e);
  }
}

// Get List of Landmarks (sync operation)
function getListLandmarks(imgId)
{
  var sort = new Object();
  sort.Key = 'LandmarkName';
  sort.Order = 'Descending';
  var criteria = new Object();
  criteria.Type = 'Landmark';
  criteria.Sort = sort;
  try
  {
    var resultList = so.IDataSource.GetList(criteria);
    if(!checkError("IDataSource::getListLandmarks",resultList,DIV_ID,imgId)) {
      document.getElementById(DIV_ID).innerHTML = showIterableList(resultList.ReturnValue);
    }
  }
  catch(e)
  {
    showIMG(imgId,"no");
    alert ("getListLandmarks: " + e);
  }
}

// Get List of Landmarks (Async operation)
function getListLandmarksAsync(imgId)
{
  var sort = new Object();
  sort.Key = 'LandmarkName';
  sort.Order = 'Descending';
  var criteria = new Object();
  criteria.Type = 'Landmark';
  criteria.Sort = sort;
  try
  {
    imgid_callback2 = imgId;
    var resultList = so.IDataSource.GetList(criteria, callback2);
    if(!checkError("IDataSource::getListLandmarksAsync",resultList,DIV_ID,imgId))
      showIMG(imgId, "");
  }
  catch(e)
  {
    showIMG(imgId,"no");
    alert ("getListLandmarksAsync: " + e);
  }
}

// cancel get categories
function cancelCategoriesAsync(imgId)
{
  // Setup input params using dot syntax
  var criteria = new Object();
  criteria.Type = 'Category';
  try
  {
    imgid_callback1 = imgId;
    var resultList = so.IDataSource.GetList(criteria, callback1);
    if(!checkError("IDataSource::cancelCategoriesAsync",resultList,DIV_ID,imgId)) {
      showIMG(imgId, "");
      var criteria2 = new Object();
      criteria2.TransactionID = resultList.TransactionID;
      var resultList2 = so.IDataSource.Cancel(criteria2);
      checkError("IDataSource::cancelCategoriesAsync",resultList2,DIV_ID,imgId);
    }
  }
  catch(e)
  {
    showIMG(imgId,"no");
    alert ("cancelCategoriesAsync: " + e);
  }
}

// cancel get landmarks
function cancelLandmarksAsync(imgId)
{
  var sort = new Object();
  sort.Key = 'LandmarkName';
  sort.Order = 'Descending';
  var criteria = new Object();
  criteria.Type = 'Landmark';
  criteria.Sort = sort;
  try
  {
    imgid_callback2 = imgId;
    var resultList = so.IDataSource.GetList(criteria, callback2);
    if(!checkError("IDataSource::cancelLandmarksAsync",resultList,DIV_ID,imgId)) {
      showIMG(imgId, "");
      var criteria2 = new Object();
      criteria2.TransactionID = resultList.TransactionID;
      var resultList2 = so.IDataSource.Cancel(criteria2);
      checkError("IDataSource::cancelLandmarksAsync",resultList2,DIV_ID,imgId);
    }
  }
  catch(e)
  {
    showIMG(imgId,"no");
    alert ("cancelLandmarksAsync: " + e);
  }
}

// Delete one Category (sync operation)
function deleteCategory(imgId)
{
  var landmarkIdStr = prompt("Please type the landmark id", "0");
  if(landmarkIdStr == "" || landmarkIdStr == null)
    return;

  // Setup input params using dot syntax
  var data = new Object();
  data.id = parseInt(landmarkIdStr);
  var criteria = new Object();
  criteria.Type = 'Category';
  criteria.Data = data;
  try
  {
    var resultList = so.IDataSource.Delete(criteria);
    checkError("IDataSource::deleteCategory",resultList,DIV_ID,imgId);
  }
  catch(e)
  {
    showIMG(imgId,"no");
    alert ("deleteCategory: " + e);
  }
}

// Delete one Landmark (sync operation)
function deleteLandmark(imgId)
{
  var landmarkIdStr = prompt("Please type the landmark id", "0");
  if(landmarkIdStr == "" || landmarkIdStr == null)
    return;

  // Setup input params using dot syntax
  var data = new Object();
  data.id = parseInt(landmarkIdStr);
  var criteria = new Object();
  criteria.Type = 'Landmark';
  criteria.Data = data;
  try
  {
    var resultList = so.IDataSource.Delete(criteria);
    checkError("IDataSource::deleteLandmark",resultList,DIV_ID,imgId);
  }
  catch(e)
  {
    showIMG(imgId,"no");
    alert ("deleteLandmark: " + e);
  }
}

// Export specific Landmarks to xml file (sync operation)
// When we export file already exist it returns an errorCode !!!
function exportLandmarks(imgId)
{
  // Setup input params using dot syntax
  var data = new Object();
  data.DestinationFile = 'landmarks-export.xml';
  data.MimeType = 'application/vnd.nokia.landmarkcollection+xml';
  data.IdList = [ "3", "4" ];
  var criteria = new Object();
  criteria.Type = 'Landmark';
  criteria.Data = data;
  try
  {
    var resultList = so.IDataSource.Export(criteria);
    checkError("IDataSource::exportLandmarks",resultList,DIV_ID,imgId);
  }
  catch(e)
  {
    showIMG(imgId,"no");
    alert ("exportLandmarks: " + e);
  }
}

// Import Landmarks from xml file (sync operation)
function importLandmarks(imgId)
{
  // Setup input params using dot syntax
  var data = new Object();
  data.SourceFile = 'landmarks-export.xml';
  data.MimeType = 'application/vnd.nokia.landmarkcollection+xml';
  var criteria = new Object();
  criteria.Type = 'Landmark';
  criteria.Data = data;
  try
  {
    var resultList = so.IDataSource.Import(criteria);
    checkError("IDataSource::importLandmarks",resultList,DIV_ID,imgId);
  }
  catch(e)
  {
    showIMG(imgId,"no");
    alert ("importLandmarks: " + e);
  }
}

// Organise Landmarks with entered ladmark id (sync operation)
function organiseLandmarks(imgId)
{
  // Setup input params using dot syntax
  var landmarkIdStr = prompt("Please type the landmark id", "0");
  if(landmarkIdStr == "" || landmarkIdStr == null)
    return;

  var data = new Object();
  data.id = parseInt(landmarkIdStr);
  data.IdList = [ "3", "4" ];
  var criteria = new Object();
  criteria.Type = 'Landmark';
  criteria.Data = data;
  criteria.OperationType = 'Associate';
  try
  {
    var resultList = so.IDataSource.Organise(criteria);
    checkError("IDataSource::organiseLandmarks",resultList,DIV_ID,imgId);
  }
  catch(e)
  {
    showIMG(imgId,"no");
    alert ("organiseLandmarks: " + e);
  }
}

// This is the asynchronous callback handler
function callback1(transId, eventCode, result)
{
  console.info("callback1: transId: %d  eventCode: %d result.ErrorCode: %d", transId, eventCode, result.ErrorCode);
  if(!checkError("IDataSource::getListCategoriesAsync",result,DIV_ID,imgid_callback1)) {
    document.getElementById(DIV_ID).innerHTML = showIterableList(result.ReturnValue);
  }
}

// This is the asynchronous callback handler
function callback2(transId, eventCode, result)
{
  console.info("callback2: transId: %d  eventCode: %d result.ErrorCode: %d", transId, eventCode, result.ErrorCode);
  if(!checkError("IDataSource::getListLandmarksAsync",result,DIV_ID,imgid_callback2)) {
    document.getElementById(DIV_ID).innerHTML = showIterableList(result.ReturnValue);
  }
}