Call property set function within class in Kotlin - class

I'd like for every time my class sets a property for it to call the set function for that property.
here's what I'm trying to do:
var text = ""
set(value) {
field = value
//Do some other things
....
}
...
fun someFunction() {
...
//This should do everything in the set function, not just set the value
text = "new text"
...
}
I've tried doing this.text = "new text", but that still just set the value of text to new text. Is there a way to call that set function from within my class, or do I have to create a separate setText function, like I would do in Java?

You already call the setter. It just happens that you only call field = value inside it. Try using println function inside it and see that the setter is indeed called.

Related

Change variable value with what is in a function

I have values in my function that I want to put into the labels that I have linked to my viewController. I tried to do currentTempLabel.text = result.main.temp but it did not want to do that in the function. So I moved that to the viewDidLoad and made some variables, var temp: String = "". In my function I have it set the variable to the value that I get from the API in that function but it doesn't set it to the value. When I run the app it just comes up with the default values that I put into it.
Right now I have the values printing to the console but I need the to go to the actual app and display. This is probably something very simple but I just can't figure it out.
In the function I have:
self.temp = String(result.main.temp)
And in viewDidLoad I have:
currentTempLabel.text = temp
In my mind this should work but not in Swift's mind.
The API to get the weather data works asynchronously. Assign the value to the label in the completion handler on the main thread
DispatchQueue.main.async {
self.currentTempLabel.text = String(result.main.temp)
}

Annotate getter from the property

In kotlin, we can define
var text: String
which will have a getter and a setter. It's easy to remove the setter by changing it to val, but what if we have a property that should only have the setter and no getter? Is there any way to create an annotation that we can apply to text that will deprecate the getter so others cannot use it?
The end goal is to be able to use the property syntax rather than call setText
Current workaround I am aware of that achieves a similar result:
var text: String
#Deprecated(level = DeprecationLevel.ERROR, message = "Non readable property")
get() = nonReadable()
set() ...
I would like to know if it's possible to define something similar to
#SetterOnly
var text: String
set() ...
I can tell you that there is no way to complete this feature in kotlin now. since the bug KT-3110 is not marked as Fixed.
I have test the following java code in kotlin at below, it only can access setter via setText:
public class Property {
public void setText(String text) {/**/}
private String getText() { return "foo"; }
}
which means you can't remove the getter/make the getter's visibility down. so it is impossible to get rid of the getter like as kotlin-allopen plugin. so one possible solution you can do is write your own kapt plugin to throws a compile-time error, for example:
#SetOnly var text:String = "foo";
If you don't want this property to be used externally, why dont you declare it as
private var text :String =""

Setter for Bool in Swift

I'm using a custom getter like so
var currentShowLiked: Bool {
get {
return [some condition met] ? true : false
}
set {
self.currentShowLiked = newValue
}
}
and it works fine. However, I would expect to be able to set true or false value back to my variable, but Swift forced my to implement a setter, which does not produce any warnings, but at runtime if I'm to change value of my variable, app crashes with no apparent reason or sane explanation pointing to setter line with EXC_BAD_ACCESS (code=2...) and a message in console warning: could not load any Objective-C class information. This will significantly reduce the quality of type information available.
Why do I do?
You are in recursive context.
You can't use currentShowLiked in the currentShowLiked property body as below:
// Recursive, Infinite loop
self.currentShowLiked = newValue
To fix this:
private var _currentShowLiked : Bool
var currentShowLiked: Bool {
get {
return [ some condition met on _currentShowLiked ] ? true : false
}
set {
self._currentShowLiked = newValue
}
}
A Swift property that defines a custom getter and / or setter operation is a computed property which does not actually stores a value. The custom setter can be used to modify the internal state of other properties.
See also: "The Swift Programming Language" page 180
You can not set value in its setter because you are creating a recursion -method calling itself because:
self.currentShowLiked = newValue
will call set method you defined which will go and go. If you are overriding setter and getter you probably want to have some backing store property which will be private.
Moreover you defined a getter which base on some condition so anyway you are not using the value you set on this property. I think you do not need this set
The error here is caused by a misunderstanding.
When you declare a
var a:Type
A member value a is allocated inside the object, and accessors and mutators are automatically created to allow you to read and write that variable.
However, when you declare
var a:Type { get { ... } set { ... } }
No member value is allocated - you have indicated that when the value is accessed (read) or mutated (written) from a user of the object, your code will do all necessary action to respond to it. If you ultimately want the value to be stored, you will need to store it to an actual value, (which will need a different name).
Since you are invoking the mutator of the object inside the mutator of the object, you have set up an infinite loop, which causes your program to crash due to stack overflow (all function call memory is used to store the record of the function calling itself over and over again).
The code you have above will crash because it causes an infinite loop - your setter for currentShowLiked sets currentShowLiked to the new value, so then that calls the setter again, and so on.
You don't have to implement a setter, but you then don't use get - the syntax is like this:
var currentShowLiked: Bool {
return [some condition met]
}

Restangular extendModel on new object

Restangular offers a feature, extendModel, which lets you add functionality onto objects returned from the server. Is there any way to get these methods added to an empty / new model, that hasn't yet been saved to the server?
I wanted to do the same thing but didn't find an example. Here's how I ended up doing it:
models.factory('User', function(Restangular) {
var route = 'users';
var init = {a:1, b:2}; // custom User properties
Restangular.extendModel(route, function(model) {
// User functions
model.myfunc = function() {...}
return model;
});
var User = Restangular.all(route);
User.create = function(obj) {
// init provides default values which will be overridden by obj
return Restangular.restangularizeElement(null, _.merge({}, init, obj), route);
}
return User;
}
Some things to be aware of:
Use a function like _.merge() instead of angular.extend() because it clones the init variable rather than simply assigning its properties.
There is a known issue with Restangular 1.x that causes the Element's bound data to not be updated when you modify its properties (see #367 and related). The workaround is to call restangularizeElement() again before calling save(). However this call will always set fromServer to false which causes a POST to be sent so I wrote a wrapper function that checks if id is non-null and sets fromServer to true.

accessing global variable inside javascript nested function

I want to access global variable inside javascript nested function and append some value inside the nested function and display that variable out side the nested function with the value appended in nestedfunction
eg:
function a()
{
var res="";
function b()
{
res=res+"hello";
alert(res); //alert dialog with hello is appearing
}
alert(res); //empty alert dialog is appearing,but I want this alert to
display hello,means "res" must act as global variable.
}
can you please give the solution for this.....
Sorry, but your code is complete mess. Try this:
var res="A";
b();
alert(res);
function b()
{
res=res+"hello";
alert(res);
};