How to store values even after the application restarts? - database

When creating applications with ApplescriptObjC you can create a property like this:
property myValue : "value"
However, if I change the value of this variable, it will get set back to "value" whenever the application restarts. How can I store values so they do not get reset after the application restarts?

You'll need to store your value somewhere before your application quits. Using NSUserDefaults is the best approach:
property NSUserDefaults : ((current application)'s NSUserDefaults's standardUserDefaults)
To save your value, use the following code, where myKey can be any string, and val is the value that you want to save:
NSUserDefaults's setObject:val forKey:myKey
To retrieve your value later on, you can use:
NSUserDefaults's objectForKey:myKey
By the way, NSUserDefaults has several useful functions for getting values, depending on the type of data stored. For example, if you were storing a boolean, you could use "boolForKey:".
However, you should set a default value for your key, in case it has never been saved before. This must be done before trying to retrieve the value for your key, where defVal is the default value:
NSUserDefaults's registerDefaults:((current application)'s NSDictionary's dictionaryWithObject:defVal forKey:myKey)
If you'd like to know more about NSUserDefaults, you can read about it here: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/

Related

How to map array of objects

I have some problems mapping an array of objects in JS.
This is how the response looks in my console:
[{...}]
...and when I expand it I get this:
0:{id:0, document:{...}}
1:{id:1, document:{...}}
Usually the response I get is always without this number in front of each object, like this:
{id:0, document:{...}
{id:1, document:{...}
I tried every approach I know and I cant't manage to handle it.
The goal is to take each value out of "document" property and dynamically display it in some kind of table.
This is the way the browser devtools decides to display the array, but it is actually correct, if I'm not mistaken you're still dealing with an array.
You can verify this by logging the following:
(Replace myVar with the variable name you chose for your response array)
console.log(Array.isArray(myVar))
If it outputs true then you're fine and you are dealing with an array.

How best to store a number in google realtime model, and get atomic change events?

Sounds pretty simple, however...
This number holds an enumerated type, and should be a field within a custom realtime object. Here's its declaration in the custom object registration routine:
MyRTObjectType.prototype.myEnumeratedType =
gapi.drive.realtime.custom.collaborativeField('myEnumeratedType');
I can store it in the model as a simple javascript number, and initialize it like this:
function initializeMyRTObjectType() {
// other fields here
this.myEnumeratedType = 0;
}
...but the following doesn't work, of course, since it's just a number:
myRTObject.myEnumeratedType.addEventListener(
gapi.drive.realtime.EventType.OBJECT_CHANGED, self.onTypeChanged);
I can add the event listener to the whole object:
myRTObject.addEventListener(
gapi.drive.realtime.EventType.OBJECT_CHANGED, self.onTypeChanged);
But I'm only interested in changes to that number (and if I were interested in other changes, I wouldn't want to examine every field to see what's changed).
So let's say I store it as a realtime string, initializing it like this:
function initializeMyRTObjectType() {
var model = gapi.drive.realtime.custom.getModel(this);
// other fields here
this.myEnumeratedType = model.createString();
}
Now I'll get my change events, but they won't necessarily be atomic, and I can't know whether a change, say from "100" to "1001", is merely a change enroute to "101", and so whether I should react to it (this exact example may not be valid, but the idea is there...)
So the question is, is there either a way to know that all (compounded?) changes, insertions/deletions are complete on a string field, or (better) a different recommended way to store a number, and get atomic notification when it has been changed?
You also get a VALUE_CHANGED event on the containing object like you would for a map:
myRTObject.addEventListener(gapi.drive.realtime.EventType.VALUE_CHANGED,
function(event) {
if (event.property === 'myEnumeratedType') {
// business logic
}
});

Firebase get value out of array

I'm making a realtime app with AngularJS and Firebase. I'm storing an array of data (players).
Below you can see a sample of my datastructure.
I can get all the players of this particular game, but how do I get for instance the player 'test'? The key is a generated value:
Game.find(gameId).child('/players/').push(player);
Then I thought, why don't I just 'update' '/players/'+name and set the name there. But unfortunatly I'm getting back objects inside an object:
{
players : {
"name":"...",
"test":"moretest"
}
}
I can access these properties but I cannot loop over them because it's not an array.
So basically what I want to do is "linq-wise" getting a player out of an array.
Game.find(gameId).child('/players/').where( name == ...);
Thanks in advance
Edit:
You are on the right track with storing just the name of the player instead of using push to generate an ID. You'll need to make sure your player names are unique though, otherwise you risk not being able to accommodate two players with the same name.
Every key in Firebase must have a value, so the best way to store a list of players where you want them to be accessible by the player name is to simply set them to a boolean value like 'true':
Game.find(gameId).child('/players').child(player).set(true);

Make variable name using loop and string in PowerBuilder

I am interested if it is possible to make variable name in PowerBuilder using a loop and a string. For example:
long ll_go
string lst_new
for ll_go = 1 to 8
lst_new = "text" + ll_go
lst_new.tag = 5500
next
So, it should give me variables text1, text2..,.,text8 and I would be able to assign values for them. Let me know if anybody succeeded, thanks in advance
Your description is lacking some term precision.
If you actually want to dynamically create new variables as "variable in a powerscript subroutine or function" this is simply not possible.
If instead you want to create dynamically some new controls statictext or textedit objects in a window or visual userobject this is possible:
use a local variable of the type of the new object you need to create, e.g. static text
make it a live object (instantiate) with create
set the object properties to whatever you need
"attach" the new object to its parent (either a window or a visual userobject - though any graphicobject is possible with using the win32api SetParent function) with the OpenUserObject() method. Note that you cannot simply add it directly to the parent's Control[] array.
you can also keep the object in your own array for later convenience access to the created objects instead of looping on the Control[] array
once the object is attached it its parent, you can reuse the local variable to create another one
Here is an example:
//put this in a button clicked() event on a window
//i_myedits is declared in instances variables as
//SingleLineEdit i_myedits[]
SingleLineEdit sle
int i
for i = 1 to 8
sle = create singlelineedit
sle.text = string(i)
sle.tag = "text_" + string(i)
sle.height = pixelstounits(20, ypixelstounits!)
sle.width = pixelstounits(100, xpixelstounits!)
parent.openuserobject(sle, pixelstounits(10, xpixelstounits!), pixelstounits(22 * i, ypixelstounits!))
i_myedits[i] = sle //keep our own reference
next
An exemple of values access:
//put that in another button clicked() event
SingleLineEdit sle
int i
string s_msg
for i = 1 to upperbound(i_myedits[])
sle = i_myedits[i]
if i > 1 then s_msg += "~r~n"
s_msg += "edit #" + string(i) + " (" + sle.tag + ") says '" + sle.text + "'"
next
messagebox("Edits values", s_msg)
As you can see, one practicality problem is that you cannot refer to these controls by constructing the control's name like "text"+2, instead you must access the my edits[] array or loop through the controls and test their .tag property if you set it to something specific.
I do not think that it is possible. Workaround could be an array maybe.
Br. Gábor
I'd see two ways to do this, but they aren't as easy as it seems that you were hoping:
1. Control Array
First method would be to go through the control arrays (on windows, tabs and user objects). I'd create a function that took the control name as a string, then another that overloaded the same function and took control name and an array of windowobject. The string-only method would just call the string/array method, passing the string through and adding the window.Control as the second parameter. The string/array method would go through the array, and for each element, get the ClassDefinition. Pull the name off of it, and parse it apart the way you want it to match the string parameter (e.g. for w_test`tab_first`tabpage_first`cb_here, do you want cb_here to match, or tab_first`tabpage_first`cb_here?). Deal with matches as appropriate. When you find a control of type tab or user object, call the string/array function again with the Control array from that object; deal with success/fail returns as appropriate.
2. DataWindow
What you're describing works extremely well with DataWindows, and their Describe() and Modify() functions. Since you pass these functions only a string, you can build not only the control names, but the values they're set to as you would build any string. In fact, you can build multiple Modify() strings together (delimited by a space) and make a single call to Modify(); this is not only faster, but reduces window flicker and visible activity.
Don't fall into the trap of thinking that, since your data isn't from a database, you can't use a DataWindow. Create an external DataWindow, and simply use it with one row inserted during the Constructor event.
As you might guess, I'd strongly favour the DataWindow approach. Not only is it going to perform better, but it's going to provide a lot more flexibility when you want to move on and tag more control types than just static text. (You'll have to do some type casting even with one control type, but if you want to get into multiples, you'll need to start a CHOOSE CASE to handle all your types.)
Good luck,
Terry
You can't create a variable name in a script because the variables have to be declared before you can use them. With PBNI it's possible to generate a name the way you describe and then get a reference to a variable of that name that already exists but I don't think that's what you want. If you want to keep track of additional properties for your controls, just inherit a new user object from whatever it is (sle, mle, etc.) and add the properties you want. Then you can place your user object on a window and use the properties. Another approach is to use the control's Tag property. It holds a string that you can put whatever you want in. PFC uses this technique. Terry's DataWindow solution is a good approach for storing arbitrary data.
Yes, and there are more than one way to skin a cat.
Sounds like you have several properties so I'd use an array of custom non visual user objects, or an array of structures. Otherwise you could probably use something from the .NET framework like a dictionary object or something like that, or a datawidnow using an external datasource, where you can refer to column names as col + ll_index.ToString().
SIMPLE Example:
Make custom NVO with following instance variables, plus getter/setter functions for each, name it n_single_field
// add the properties and recommend getter and setter functions
public string myTag
public string myText
public int myTabOrder
...
// To USE the NVO define an unbounded array
n_single_field fields[]
// to process the populated fields
integer li_x, li_max_fields
// loop through field 1 through max using array index for field number
li_max_fields = upperbound(fields)
for li_x = 1 to li_max_fields
fields[li_x].myTag = 'abc'
fields[li_x].myText = 'text for field number ' + li_x.ToString()
fields[li_x].myTabOrder = li_x * 10
next
Maybe I'm oversimplifying if so let me know, if there is a will there is always a way. ;)

How to initialize a Ref<?> field in objectify to a dummy value

I have a collection(arraylist) of Ref `s ,the objectify documentation says that I need to initialize collections for them to be persisted and hence modified in the future.....
Now , Ref points to an object but when I launch my app for the first time I dont have any objects in the data store...so whats the best way for me to initialize a dummy value......
Is my assumption that a Ref<> needs to point to a real object in the data store?
Two things:
You should just initialize an empty collection. You don't need to add anything to it. eg, field = new ArrayList<Ref<Thing>>();
It's actually not even required that you initialize the collection. It's just a good idea for reasons that will become apparent if you use the system for a while.

Resources