Android Studio: Timber: automatically add the function name - kotlin

Does anyone know a trick to include the function name in a Timber text/tag without actually having to type it? Here's what I do and I figured I might as well ask... (initRecognizer is the function's name; ideally I enter something like $xyz)
Thank you
Timber.d("SR: initRecognizer psid=$psid")

By default, Timber uses className as the tag. You can provide your own tag by overriding createStackElementTag function while planting the tree. Something like:
Timber.plant(
object : Timber.DebugTree() {
override fun createStackElementTag(element: StackTraceElement): String {
val className = super.createStackElementTag(element)
return "TAG $className ${element.methodName}"
}
}
)
I usually use a "TAG" prefix in my tags to quickly filter my logs from logcat.
Now you simply call Timber.d("your debug msg") and the function name will automatically be added in the tag in the logcat.

Related

RazorPages anchor tag helper with multiple parameters

Here's the RazorPages page I'm trying to make a link to:
#page "{ReportId:int}/{SicCode:alpha?}"
This works
<a asp-page="/ReportSics" asp-route-ReportId="3">rs1</a>
it produces
rs1
But this produces a blank href.
<a asp-page="/ReportSics" asp-route-ReportId="3" asp-route-SicCode="10">rss2</a>
That is: the tag helper works with one parameter but not with two.
Why?
Is it possible to make it work?
(I have another page with the same #page but with the second parameter not optional and it appears to be impossible to create a link to it.)
Furthermore, requesting Page/2/M works, but Page/2/12 returns 404. Why? (The second parameter is a string that can sometimes be a number, but it always treated as a string.)
From the learn.microsoft.com webpage asp-all-route-data offers the following:
asp-all-route-data
The asp-all-route-data attribute supports the creation of a dictionary of key-value pairs. The key is the parameter name, and the value is the parameter value.
In the following example, a dictionary is initialized and passed to a Razor view. Alternatively, the data could be passed in with your model.
#{
var parms = new Dictionary<string, string>
{
{ "speakerId", "11" },
{ "currentYear", "true" }
};
}
<a asp-route="speakerevalscurrent"
asp-all-route-data="parms">Speaker Evaluations</a>
The preceding code generates the following HTML:
Speaker Evaluations
Extension: From here the parameters can be accessed either explicitly in the parameter list of the method:
public IActionResult EvaluationCurrent(int speakerId, string currentYear)
or as a collection (See response: queryString:
public IActionResult EvaluationCurrent()
{
var queryString = this.Request.Query;
}
This works
Yes it works because it produces a route that is similar to this baseUrl/reportsics/?reportId=5
And the other produces a URL that is similar to this baseUrl/reportsics/?reportId=5&sicCode=678 and then it doesn't match your route definition. I think you should try this.
Experimental
asp-page="/reportSics/#myId/#sicCode
Though this would not be the right way to do what you're thinking. If you really want to change your URL structure, why not do url-rewrite?
Edit.
Form your recent comments, seems you want to pass many parameters in your action method and not targeting URL structure. Then I recommend you just
public IActionResult(string ReportId, string sicCode)
{
//......
}
//And the your URL target
<a asp-page="ReportSics" asp-route-ReportId="55" asp-route-sicCode="566" ></a>
And then it will match the route. I think you should remove that helper you placed after your #page definition and try it out if this is what you have already done and the problem persists.
It turns out that if a parameter has the constraint :alpha then it only works if the value being passed can not be parsed as an int or float.

custom boolean attributes not binding

Custom boolean attributes do not bind like built in. checked.bind='1===2' will not include the checked attribute in the tag. myboolatt.bind='1===2' WILL include the myboolatt in the tag. I did myboolatt.bind='1===2 | boolconverter' to log out the value and it says false.
So what am I doing wrong? It seems Aurelia is inconsistent on binding expressions. Another instance is I can do this title=${$index<12} inside a repeat and I get what is expected. So I thought this would work - myboolatt.bind=${$index<12}. That doesn't even compile.
Believe me I have read the all the doc (doesn't mean I didn't miss something) and many posts including the long running discussions between the Aurelia team concerning boolean attributes.
I have wrapped expressions in "" and in ${} and in both but just can't get it to work.
It feels like I am missing 1 vital piece of information that will magically explain these inconsistencies and slay my frustration. One of the reasons I like Aurelia so much (on top of convention based) is that I have actually just guessed at a few things - thinking this is how I would do it - and ding-dang if they didn't just work.
I really feel like this should just work. So again I ask - what am I doing wrong?
Thanks
If you are using .bind, you bind it to the att variable in your js/ts file, and you should not use any dollar signs or brackets.
For example, myboolatt.bind=${$index<12} should be myboolatt.bind="$index<12". The use of the dollar sign in index has nothing to do with the bindings. This is just a variable provided by Aurelia.
When you want to use variables without bind you use ${variable}.
The checked attribute not being present, I in the tag I'm guessing is because it's evaluated to false, and the checked attribute is not a true/false attribute. A input that's checked will look like <input type="checkbox" checked/>
It was not Aurelia binding. I initially created bool attributes but did not have a need to bind. They were just empty classes. Then I needed binding so I added the necessary methods. What ended up causing the confusion was using myboolatt sends no argument into valueChanged where myboolatt.bind sends T or F. Not being a regular js'er this threw me a bit and I see there are a number of ways to handle. Anyway here are the attributes and usage. Hope it helps someone else.
Thanks
function private_ValueChanged(self, att, value) {
if (value === false) self.element.removeAttribute(att);
else self.element.setAttribute(att, '');
}
export class toggleCustomAttribute {
static inject = [Element];
constructor(element) { this.element = element; }
valueChanged(newValue, oldValue) { private_ValueChanged(this, 'toggle', newValue);
}
export class radioCustomAttribute {
static inject = [Element];
constructor(element) { this.element = element; }
valueChanged(newValue, oldValue) { private_ValueChanged(this, 'radio', newValue); }
}
<ff-button repeat.for="keymen of keyChangeMenu" radio.bind="$index<12" class='ff-button' click.delegate="keyChangeClick($event.target)" id.bind="$index+'_key'" >
${keymen[0]}<sup>${keymen[1]}</sup>
</ff-button>

Reference value of constant with KDoc

I have a object like the following in my project
object UrlUtils {
private const val PARAM = "whatever"
/**
* Method that appends the [PARAM] parameter to the url
*/
fun appendParameter(url: String) {
// ...
}
}
As you can see a I wanna reference the value of the PARAM field in the KDoc comment of the appendParameter method however when looking at the comment I don't see the actual value but only the name of the field.
Method that appends the PARAM parameter to the url
What I want:
Method that appends the whatever parameter to the url
In Javadoc this works by using {#value PARAM} but there seems to be nothing similar in KDoc. Even the automatic code-converter keeps the old Javadoc.
So my question: Am I missing something or is KDoc/Dokka missing this feature?
Currently, {#value} tags are not supported by KDoc.
The closest issue requesting this is #488, so you can up-vote and/or comment on it.

Accessing Resources IDs using Kotlin & Anko

I am new to Android/Kotlin/Anko and I have a question regarding the way to access color (and probably other) resources from within Anko.
I know that there are helpers like textResource where you simply pass the R.string.my_color to simplify the process of setting resource strings but how about accessing colors using the Resources instance from the View class ?
Let’s say you have a subclass of Button and want to change the text color. If you use the textResource it will change the text string not the color, and if you use textColor then you must specify the real resource ID by using resources.getColor(R.color.my_color, null) which wouldn't be so annoying if you didn't have to pass the optional theme parameter (null here)
Is creating an extension on Resources useful here ?
fun Int.fromResources(resources: Resources): Int {
return resources.getColor(this, null)
}
What is the recommended way ?
EDIT
I changed the textColor value extension to do just that, which I found the cleanest thing to do except I have no idea if this is really Android friendly
var android.widget.TextView.textColor: Int
get() = throw AnkoException("'android.widget.TextView.textColor' property does not have a getter")
set(v) = setTextColor(resources.getColor(v, null))
I think you can use a property extension like this one instead of the one you suggested:
var TextView.textColorRes: Int
get() = throw PropertyWithoutGetterException("textColorRes")
set(#ColorRes v) = setTextColor(resources.getColor(v, null))
Or use ContextCompat as suggested by Damian Petla:
var TextView.textColorRes: Int
get() = throw PropertyWithoutGetterException("textColorRes")
set(#ColorRes v) = setTextColor(ContextCompat.getColor(context, v))
You should keep Anko's textColor:
Allows you to set a color directly without taking it from XML, if needed at some point
Prevents you from importing the wrong textColor (Anko's one or yours), same property names with different behaviour is not a good idea.

An interesting Restlet Attribute behavior

Using Restlet 2.1 for Java EE, I am discovering an interesting problem with its ability to handle attributes.
Suppose you have code like the following:
cmp.getDefaultHost().attach("/testpath/{attr}",SomeServerResource.class);
and on your browser you provide the following URL:
http://localhost:8100/testpath/command
then, of course, the attr attribute gets set to "command".
Unfortunately, suppose you want the attribute to be something like command/test, as in the following URL:
http://localhost:8100/testpath/command/test
or if you want to dynamically add things with different levels, like:
http://localhost:800/testpath/command/test/subsystems/network/security
in both cases the attr attribute is still set to "command"!
Is there some way in a restlet application to make an attribute that can retain the "slash", so that one can, for example, make the attr attribute be set to "command/test"? I would like to be able to just grab everything after testpath and have the entire string be the attribute.
Is this possible? Someone please advise.
For the same case I usually change the type of the variable :
Route route = cmp.getDefaultHost().attach("/testpath/{attr}",SomeServerResource.class);
route.getTemplate().getVariables().get("attr") = new Variable(Variable.TYPE_URI_PATH);
You can do this by using url encoding.
I made the following attachment in my router:
router.attach("/test/{cmd}", TestResource.class);
My test resource class looks like this, with a little help from Apache Commons Codec URLCodec
#Override
protected Representation get() {
try {
String raw = ResourceWrapper.get(this, "cmd");
String decoded = new String(URLCodec.decodeUrl(raw.getBytes()));
return ResourceWrapper.wrap(raw + " " + decoded);
} catch(Exception e) { throw new RuntimeException(e); }
}
Note my resource wrapper class is simply utility methods. The get returns the string of the url param, and the wrap returns a StringRepresentation.
Now if I do something like this:
http://127.0.0.1/test/haha/awesome
I get a 404.
Instead, I do this:
http://127.0.0.1/test/haha%2fawesome
I have URLEncoded the folder path. This results in my browser saying:
haha%2fawesome haha/awesome
The first is the raw string, the second is the result. I don't know if this is suitable for your needs as it's a simplistic example, but as long as you URLEncode your attribute, you can decode it on the other end.