0

I have a Titanium/Appcelerator app created using Alloy models, which uses Backbone.js. Each model has a text field that I would like to interpret as a number. So far I've been getting the property and converting it using parseInt() each time I need to use it.

Is there a way to automatically interpret that property as a number every time I access it? Perhaps some kind of automatic conversion? I would like to avoid changing the type of the field in the database and having to do some kind of migration.

Here is a stripped down example of my model. The property date is saved to the database as a string. But because it's a UTC timestamp, I want to always interpret it as a number.

exports.definition = {
    config: {
        columns: {
            "name": "text",
            "date": "text" 
        },
        adapter: {
            type: "sql",
            collection_name: "people"
        }
    },
    extendModel: function(Model) {
        _.extend(Model.prototype, {
            // extended functions and properties go here
        });

        return Model;
    },
    extendCollection: function(Collection) {
        _.extend(Collection.prototype, {
            // extended functions and properties go 
        });

        return Collection;
    }
};
shrewdbeans
  • 11,971
  • 23
  • 69
  • 115
  • Refer to the approach of overriding Model.get() on this thread: http://stackoverflow.com/questions/6695503/whats-the-best-way-to-override-model-getattr-in-backbone-js. You could return a parseInt() value when attr == date. – Nirmal Patel Jan 19 '17 at 19:03

1 Answers1

2

You can extend your model like this:

exports.definition = {
   config: {
    columns: {
        "name": "text",
        "date": "text" 
    },
    adapter: {
        type: "sql",
        collection_name: "people"
    }
  },

  extendModel: function(Model) {
    _.extend(Model.prototype, {

        transform: function transform() {
           var transformed = this.toJSON();
           transformed.date = parseInt(transformed.date);
           return transformed;
        }
    });
    return Model;
  },

  extendCollection: function(Collection) {
    _.extend(Collection.prototype, {
        // extended functions and properties go 
    });

    return Collection;
  }
};

OR

You can use dataTransform read here attribute on your UI element to apply the transformation method.

view.xml

<Alloy>
    <Collection src="your_collection_name" />
    <Window class="container">
        <TableView dataCollection="your_collection_name" dataTransform="transformFunction">

        </TableView>
    </Window>
</Alloy>

view.js

function transformFunction(model) {
    var transformed = this.toJSON();
        transformed.date = parseInt(transformed.date);

    return transformed;
}

This is how you can use your transform method to modify the attributes, or you can also add any custom attribute to your model and refer it by same name.

Prashant Saini
  • 3,539
  • 1
  • 10
  • 24
  • It doesn't work for me, I put a `console.log` in the transform method and it looks like it's not being invoked. Am I missing a step? – shrewdbeans Jan 19 '17 at 07:14
  • @shrewdbeans - I have added a code to modify the model as per your requirement. Try and let me know. – Prashant Saini Jan 19 '17 at 07:27
  • That works for data binding on the TableView, but unfortunately each time I access the date value in another way (via sorting methods for example), it still comes out as a string. Is there a way to _always_ ensure it comes out as a string. I'm also still not seeing the `transform` method in the Model extend method being invoked. Thanks for your help. – shrewdbeans Jan 19 '17 at 09:10
  • I don't think it's possible to directly retrieve integer value of string. You will anyhow need to extend a method like in data-binding or you can convert the string to int in model.map method. Simplest way to handle this is that you change the **date** column to **"date": "integer"** because by having an integer format, you won't need to convert it into string. – Prashant Saini Jan 19 '17 at 09:47
  • If I change the date column of the table from string to integer, could this have an adverse effect on the database? I know that the strings which get stored in the column only contain numbers and no other characters. – shrewdbeans Jan 24 '17 at 18:55