Skip to main content
1-Visitor
February 23, 2016
Question

Update Single InfoTable Row with a Service

  • February 23, 2016
  • 3 replies
  • 13181 views

I've been working on this for a while now, and I'm getting a little frustrated with what I think is probably a simple thing to implement.  But I'm on my first ThingWorx project and don't have a lot of "real-world" experience with the product.  Here's some background on my situation:

I have a Thing defined that holds a customer's factory information (name, address, contact info, etc.).  One of the properties on that Thing is an InfoTable that contains area/group information within that Factory.  A good example of an area/group is "Production Line" or "Staging Area" or "Shipping" or "Lunch Room".  There is additional information tied to each group: capacity, square footage, etc.

The area/groups are used for human-readable tabulated information only (i.e. they don't require any special services/functionality other than adding, updating, and deleting groups).  For this reason, I chose to make this an InfoTable on the Factory Thing instead of making each area/group its own Thing (which would feel like an overly complex data architecture to me).  Due to customer requirements that are inflexible, this data MUST be maintained via an external application using the REST API.  Additionally, group data can come from multiple sources that don't necessarily have ALL the Factory's area/group data (i.e. a given department may only have access to its own areas/groups within this external application and multiple instances of the application are not connected to each other--they do not know about each other's data).

With that background in mind, I need to use the REST API to add rows to the InfoTable property, update a single row on the InfoTable property when the user updates that data on the external application, and delete a single row on the InfoTable property when deletes happen on the external application.  For the updates, I'm attempting to use a service on the Factory Thing that can be POSTed to and initiate updates to the InfoTable, but I keep running into issues.  What I want to do is send a REST POST with an ID value (stored on the InfoTable) along with any data changes and have the initiated service only update the single row with the new data on the request.

Long story, short: I need to create a service that will update an InfoTable property like I would update a MySQL table using this:

UPDATE Factory.AreaTable SET areaName=requestAreaName WHERE areaID=requestAreaID;

Any help is greatly appreciated!

3 replies

February 24, 2016

Hi Dean,

Please make sure that your DataShape having primary key on ID column. in your case areaID should be primary column.

Please refer below code, Printers is a infotable property of Thing. And PrinterName is a primary key of DataShape.

To Update specific row's column value:

var PrinterList = Things["ThingName"].Printers;

var PrinterName = "MyPrinter";

for (var i = 0; i < PrinterList.rows.length; i++) {

    var row = PrinterList.rows;

 

    if (row.PrinterName == PrinterName) {

        PrinterList.rows.PrinterDescription = "PrinterDescription";

        PrinterList.rows.PrinterEnabled = true;

  }

}

To delete particular row:

Things["ThingName"].Printers.Delete({PrinterName : PrinterName});

Thanks,

Lalit

1-Visitor
February 24, 2016

Hi,

  1. Never update a property infotable directly, always use clone function ( on the infotable ) and once you applied the changes to the cloned infotable then set the property with the whole new infotable.
    1. var clonedData = Resources["InfotableFunctions"].Clone( { t1: me.infotableProperty });
    2. // -- Do whatever update/insert/delete operation you want with new clonedData infotable
    3. me.infotableProperty = clonedData;
  2. For your use case, and as Property Infotables always has to be updated as a whole, you will face too many concurrent situations, for that reason better you go with a DataTable to store that data, then you will have atomic insert/update/delete on rows. If you want to separate the data between factories, you can have one DataTable for each factory, but I think that you can go with only one DataTable thing with all the data.

Best Regards,

deanm1-VisitorAuthor
1-Visitor
February 25, 2016

Thanks for the responses.  I certainly don't like the idea of clone/replace for the entire table within the service.  While single rows will be updated for each request, multiple requests could be coming in at the same time, and that approach could easily lead to overwriting previous updates.

It looks like DataTables may be a better route.  I'll look into that.

Thanks again!

22-Sapphire I
February 25, 2016

First of all, we recommend AGAINST using InfoTables as properties and you should very carefully consider your use case to determine if it makes sense. Besides the added overhead of having to write a full table for any type of updates, you are also possibly holding a lot more information in the JVM memory especially if you have many Things with an InfoTable.

The Intro to Thingworx points this out.

When you do direct operations on an InfoTable Property (as well as other Object BaseTypes like JSON) it will be treated as in Memory only and will not persist.

You don't need to call for Clone btw, you can just use

var myTempTable = me.TempTableProperty

1-Visitor
February 26, 2016

Hi Pai,

About using var myTempTable = me.TempTableProperty instead of clone, what's the difference? first operation does a copy of the infotable too? if that's the case, this is more fast or has the same performance as using clone?

Carles.