10 Replies Latest reply on Feb 26, 2016 4:01 PM by pchung RSS
    deanm Newbie

    Update Single InfoTable Row with a Service

    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!

      • Re: Update Single InfoTable Row with a Service
        lpthingworx Explorer

        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[i];

         

            if (row.PrinterName == PrinterName) {

                PrinterList.rows[i].PrinterDescription = "PrinterDescription";

                PrinterList.rows[i].PrinterEnabled = true;

          }

        }

         

        To delete particular row:

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

         

        Thanks,

        Lalit

        • Re: Update Single InfoTable Row with a Service
          carlesc Ninja

          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,

          • Re: Update Single InfoTable Row with a Service
            deanm Newbie

            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!

              • Re: Update Single InfoTable Row with a Service
                pchung Collaborator

                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

                  • Re: Update Single InfoTable Row with a Service
                    carlesc Ninja

                    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.

                    • Re: Update Single InfoTable Row with a Service
                      qn Communicator

                      Hi Pai, instead of using InfoTable as property, is there another way to receive a lot of informations sent by a device ?

                       

                      Regards,

                        • Re: Update Single InfoTable Row with a Service
                          pchung Collaborator

                          When using our EMS, you can send Properties in bulk in one message, but they still are applied to individual properties when it comes into the Thingworx platform.

                          If that option is not open, you can consider sending the InfoTable into a Service that parses the information and applies it to individual properties. However ingesting an InfoTable directly into a Property may be perfectly acceptable for your use case.

                          Ultimately this is a use case question, what do you need the information for and what do you want to do with it, that should drive how you want to acquire and ingest the information and how you want to model/structure it within the application so that it helps serve the use case.

                            • Re: Update Single InfoTable Row with a Service
                              deanm Newbie

                              For my particular situation, I need to be able retrieve, sort, query that set of properties in the same way I would an SQL table.  What I mean by that is that I need to return all corresponding properties in a row or query for a specific value and return the row that matches that value.  For example, find all areas that have a capacity over X and return their name and square footage.

                               

                              Or, perhaps, think of it like this using the common ThingWorx trucking training project.  I want my trucks to send temperature, location, capacity, weight, driver name, stop location name, and a comment after every stop.  I then want a ThingWorx mashup that allows me to select by stop location name and retrieve all of the other pieces of data because I need to know (for whatever reason) what was the temperature of the truck on those records.

                               

                              I can use a set of properties, and update all those properties with a single request. But how can I guarantee that I can retrieve all the properties for that specific "row" of data?  I thought an InfoTable might accomplish that, but it doesn't sound like it will.

                                • Re: Update Single InfoTable Row with a Service
                                  pchung Collaborator

                                  For historical information, you'd want to use a Stream or ValueStream which is meant for Data over Time.

                                  If it is more static reference information, use a DataTable

                                   

                                  IF the information is coming as a table from some other source, ie you are asking another system for all data for the week.

                                  Then easiest is to adjust the call to include filtering so it happens at the source, if that is too much traffic, you can temporarily store it within Thingworx but I'd recommend a DataTable over InfoTable.