How to use localstorage in Titanium/Alloy? - titanium

I am very new to Appcelerator/Titanium. Can anyone tell me how to use localstorage function in Alloy (Titanium). (Not getting any good solution on Web).
Thanks! :)

Titanium Alloy has a customized implemntación Backbone. This means that titanium uses Backbone for many things, but at the same time some important features have been left out.
One of the most used parts of Backbone by Titanium are models, while that not identical to those ofrese the js framework, they have lots of things in common.
To work with data models must define an adapter (this can be localStorage, sql, properties or custom sync adapters)
If you want to work with localStorage, your model should look something like this:
exports.definition = {
config: {
"defaults": {
"first_name": "",
"last_name": "",
"phone": "",
"email": ""
},
"adapter": {
"type": 'localStorage',
"collection_name": 'user'
}
},
extendModel: function(Model) {
_.extend(Model.prototype, {
}); // end extend
return Model;
},
extendCollection: function(Collection) {
_.extend(Collection.prototype, {
}); // end extend
return Collection;
}
};
to manipulate the data then you should use:
Create data
model = Alloy.createModel('user', {first_name: 'Pedro', last_name: Picapiedra});
// or model.save();
Alloy.Collections.user.add(model);
Read data
callection = Alloy.Collections.user.fetch()
model = Alloy.Collections.user.get(modelId)
Update data
user.set({
first_name : 'Pablo',
last_name : 'Marmol',
});
user.save();
Delete data
model.destroy();
collection.remove(model);
For more information:
Titanium Sync & apadters
Backbone Sync, collections, models & etc

See https://wiki.appcelerator.org/display/guides/Working+with+Local+Data+Sources for general guide.
Accessing files is done through the Ti.Filesystem. See documentation at http://docs.appcelerator.com/titanium/latest/#!/api/Titanium.Filesystem . You should also see the kitchen sink example, as it shows hot to read/write file https://github.com/appcelerator/KitchenSink/blob/master/Resources/ui/common/platform/filesystem.js.
If you simply want to store some data locally, many people use sqlite database. See http://docs.appcelerator.com/titanium/latest/#!/api/Titanium.Database .
The simplest way is to use properties. It is limited, but for many people that is enough. http://docs.appcelerator.com/titanium/latest/#!/api/Titanium.App.Properties

Related

How do I join and project a multi-map index?

I'm struggling to get my head around this one and I know the way to do this is through a custom index. Essentially, I have several collections that share some common properties, one of which is "system id" which describes a many-to-one relationship, e.g.
// Id() = "component:a"
{
"Name": "Component A"
"SystemId": "system:foo"
}
// Id() = "resource:a"
{
"Name": "Resource A",
"SystemId": "system:foo"
}
So these are two example objects which live in two different collections, Components and Resources, respectively.
I have another collection called "Notifications" and they have a RecipientID which refers to the Id of one of the entities described above. e.g.
// Id() = "Notifications/84-A"
{
"RecipientID": "component:a",
"Message": "hello component"
}
// Id() = "Notifications/85-A"
{
"RecipientID": "resource:a",
"Message": "hello resource"
}
The query that I want to be able to perform is pretty straight forward -- "Give me all notifications that are addressed to entities which have a system of ''" but I also want to make sure I have some other bits from the entities themselves such as their name, so a result object something like this:
{
"System": "system:foo",
"Notifications": [{
"Entity": "component:a",
"EntityName": "Component A",
"Notifications": [{
"Id": "Notifications/84-A",
"Message": "hello component"
}]
}, {
"Entity": "resource:a",
"EntityName": "Resource A",
"Notifications": [{
"Id": "Notifications/85-A",
"Message": "hello resource"
}]
}]
}
Where I am with it right now is that I'm creating a AbstractMultiMapIndexCreationTask which has maps for all of these different entities and then I'm trying to use the reduce function to mimic the relationship.
Where I'm struggling is with how these map reduces work. They require that the shape is identical between maps as well as the reduce output. I've tried some hacky things like including all of the notifications as part of the map and putting dummy values where the properties don't match, but besides it making it really hard to read/understand, I still couldn't figure out the reduce function to make it work properly.
How can I achieve this? I've been digging for examples, but all of the examples I've come across make some assumptions about how references are arranged. For example, I don't think I can use Include because of the different collections (I don't know how Raven would know what to query), and coming from the other direction, the entities don't have enough info to include or load notifications (I haven't found any 'load by query' function). The map portion of the index seems fine, I can say 'give me all the entities that share this system, but the next part of grabbing the notifications and creating that response above has eluded me. I can't really do this in multiple steps either, because I also need to be able to page. I've gone in circles a lot and I could use some help.
How about indexing the related docs ?
Something like this (a javascript index):
map("Notifications", (n) => {
let c = load(n.RecipientID, 'Components');
let r = load(n.RecipientID, 'Resources');
return {
Message: n.Message,
System: c.SystemId || r.SystemId,
Name: c.Name || r.Name,
RelatedDocId: id(c) || id(r)
};
})
Then you can query on this index, filter by the system value, and get all matching notifications docs.
i.e. sample query:
from index 'yourIndexName'
where System == "system:foo"
Info about related documents is here:
RavenDB Demo
https://demo.ravendb.net/demos/csharp/related-documents/index-related-documents
Documentation
https://ravendb.net/docs/article-page/5.4/csharp/indexes/indexing-related-documents

Use i18n with data fetched from Wordpress RestAPI

I'm stuck since a while on this problem now and I'm struggling to find answers or peoples that have experienced the same problem.
Also, I'm not a native English speaker and I'm new to programming, so sorry if it's not clear / if my approch is dumb as f
I decided to turn the Wordpress of my company to headless (on Nuxt). Everything was pretty fine until I tried to internationalized the app. The best solution (I think) to manage this task is to use nuxt-i18n, a tool to properly translate the app (strings, paths etc). But this solution seems to not be very compatible with data fetched from the Rest API.
For now I'm trying to passing the data from single page like that :
<script>
import SwitchL from '~/components/LanguageInput.vue'
export default {
components: {
SwitchL,
},
data() {
return {
fetchRestFr: null,
fetchRestEn: null,
i18nData: null,
}
},
i18n: {
messages: {
// help
}
},
methods: {
fetchSomeData() {
// Get page data in French
let fetchRestFr = this.$axios.$get(`https://www.company-site.com/wp-json/wp/v2/pages?include=42&lang=fr`);
// Get page data in English
let fetchRestEn = this.$axios.$get(`https://www.company-site.com/wp-json/wp/v2/pages?include=42&lang=en`);
// Assign data to null variables
this.fetchRestFr = fetchRestFr[0]
this.fetchRestEn = fetchRestEn[0]
// Build the i18n object
this.dataToI18n();
},
dataToI18n() {
if (this.fetchRestFr && this.fetchRestEn) {
let fr = this.fetchRestFr
let en = this.fetchRestEn
let data = {
messages: {
fr,
en
}
}
this.i18nData = data
}
},
},
created() {
this.fetchSomeData();
},
}
</script>
An other approch was to use the tag outside the template section like so :
<i18n>
// Inject the data generated from a function
{
"en": {
"data": "here"
},
"fr": {
"data": "ici"
}
}
</i18n>
But I don't find any solution to dynamically inject JSON here.
Last solution is to make things to preper way, by creating JSON file for i18n to referencing, but I think It will be pretty hard for me to do this, and to manage this on long term.
If you have advice, thoughts on this I will be very grateful !
You do usually use some JSON files directly. They will be stored into /locales/fr.json with something like this
{
"here": "ici"
}
Then, you'll access it into your template with
<template>
<p>{{ $t('here') }}</p>
</template>
And it will handle the fr/en switch by the several ways available (manual switch, checking browser's locale, URL's path, cookie etc).
You can check nuxt-i18n's documentation for this and get a proper simple setup quickly here: https://i18n.nuxtjs.org/
Usually, you won't need to use the i18n tag anymore but if you still need to, you can do as explained here: https://i18n.nuxtjs.org/per-component-translations

Is it possible to query document schema metadata in Sanity/GROQ?

I have a simple singleton document schema defined in my Sanity/NextJS project, to model my "Colophon" page (richText is a custom block field type):
export default {
title: 'Colophon',
name: 'colophon',
type: 'document',
__experimental_actions: ['update', 'publish'],
fields: [
{
title: 'Body',
name: 'body',
type: 'richText',
validation: Rule => Rule.required(),
},
],
};
I retrieve this document with a simple query in my NextJS application:
export async function getStaticProps() {
const colophon = await client.fetch(`
*[_type == "colophon"][0]
`);
// ...
};
Is it possible to write a GROQ query to retrieve the meta title defined in the schema, i.e. Colophon? Although this is a singleton document, I would like to avoid repeating this string in my project if possible. At the moment, I can only see the fields on the document in my results, i.e. body.
Thanks for reading!
No, I don't believe there is.
As far as I understand what you're after; The schema is defined in the studio-instance and not the datastore. Those two are not hard coupled. I have several studio-instances with small variations on the schemas using one single project/datastore. The API you query to get data does not care which studio and schema was used and cant answer for the actual schema details.

Titanium appcelerator model and collections persistance

I am about to retrieve datas from remote and create model and collections, here are each part of the app (the controller, the view and the model).
If i really understand using model in titanium is like storing into database so the data persists even if there is no internet connection after i get all datas.
Below code works well, it seems no data is displayed after connection is lost, so i ask myself what is the advantage of using models in titanium instead of using classic way : retrieve from xhr and display data ?
2- My second question (if i am wrong) after retrieving datas and storing into model, i can retrieve it without xhr again inside another page?
3- And the last one : is it a good practice to retrieve data from alloy.js and save to model because i need datas in all my app pages ?
THE CONTROLLER
// This is an istance of my xhr library
var XHR = require('xhr');
var xhr = new XHR();
$.win.addEventListener('open', function(){
url = 'mydomain.com/api/get_posts';
xhr.get(url, onSuccess, onError);
});
function onSuccess(response){
if(typeof response !== null ){
datas = JSON.stringify(response.data);
postsModel = [];
_.each(datas, function(data){
/* Create model */
postsModel.push(Alloy.createModel('mypostsmodel',{
title : data.title,
id : data.id
}));
});
$.posts.reset(postsModel);
}
}
** THE VIEW **
<Alloy>
<Collection src="myposts" instance="true" id="myposts" />
<Window id="win" title="Inscription" class="container" >
<View id="posts_view" class="myposts" dataCollection="$.myposts">
<View postId="{id}" class="post_item">
<Label class="post_label" text="{title}" />
<Label class="exp" id="exp_{id}" text="" />
</View>
</View>
</View>
</Alloy>
THE MODEL
exports.definition = {
config: {
"columns": {
"title": "Text",
"id": "Integer"
},
"defaults": {
"title": "-",
"id": "-"
},
adapter: {
type: "sql",
collection_name: "myposts"
}
},
extendModel: function(Model) {},
...
Thank you all.
The advantage in my opinion a clearer definition of the View. In my opinion the biggest thing Alloy brings to the table is the ability to more cleanly separate your view from the logic that drives your application. Your logic is also simplified (in most cases!) because all you need to do is add the data to the collection, and Alloy handles the display.
The alternative to how you are doing it:
_.each(datas, function(data){
var container = Ti.UI.createView({class: "post_item"}),
title = Ti.UI.createLabel({
text: data.title,
class: "post_label"
}),
exp = Ti.UI.createLabel({class: "exp"});
container.add(title);
container.add(exp);
$.posts_view.add(container);
});
I've done it both ways, and even with alloy, sometimes it is necessary to do this, because of the limitations of Backbone as implemented in Titanium - but I think clearly if you can include your repeating UI components in the markup, it's easier to read and maintain.

Creating and removing Ember Models dynamically / at runtime

I have been working on this for a couple of days now and have decided to bite the bullet and ask for help.
I am using ember-cli, and I'm trying to create Ember Models dynamically at runtime based on some metadata. An sample use case would be if a user wanted to specify a data set (query, file etc.); I would like to read the user's data file and setup a model based on the file's structure.
I have successfully setup an ember-cli application which uses Ember Data and Fixtures (for simplicity). My static example has three models and I can see the models and the data in the Store when I use the Chrome Ember debugger.
Now on to my dynamic example...
I have been able to successfully define a model at runtime by setting it up in IndexRoute
var IndexRoute = Ember.Route.extend({
init: function() {
// Create a simple model dynamically
var MyModel = DS.Model.extend({
defineAttributes: function(){
Ember.defineProperty(this, 'col1', DS.attr());
Ember.defineProperty(this, 'col2', DS.attr());
Ember.defineProperty(this, 'col3', DS.attr());
}.on('init')
});
// insert some data into our model
MyModel.reopenClass({
FIXTURES: [
{
id: '1',
col1: "key1",
col2: "value1",
col3: "value2"
},
{
id: '2',
col1: "key2",
col2: "value1",
col3: "value2"
},
{
id: '3',
col1: "key3",
col2: "value1",
col3: "value2"
}
]
});
}
});
The problem is that I don't see where the model has been placed, and it doesn't appear in the Chrome debugger in the Data (store).
If I change the definition of MyModel to Ember.Application.MyModel then I can see the Model is defined under Ember.Application in the console but it still isn't visible to the Ember Debugger.
I then tried to extend the above example to add the model hook as follows:
var IndexRoute = Ember.Route.extend({
init: function() {
...
},
model: function() {
return this.store.findAll('my-model');
}
});
But the call to this.store.findAll('my-model') fails in both cases. I am assuming that I am not wiring things up correctly.
In my example I am also aware that the name of my Model is not dynamic either so I really want to know how to create a name for my model programmatically at runtime.
I would really appreciate some help or guidance from those out there who are more experienced with the framework because I've been really impressed with Ember and the whole configuration over convention approach.
Thanks,
Dave
You're essentially defining something, then throwing it away. You'll need to attach it to your app's namespace (you can see it in your index file or configuration file if you're using Ember-cli).
Additionally, I doubt defining attributes on init will work, it might, but it isn't actually necessary.
Thirdly, do you really want to use Ember Data for this? Ember Data is very opinionated, and it sounds like you don't want to define things.