How do i check if a Api response exists - android

I keep getting a null pointer exception i want to see if the response exists and if so println it out.
if (responsePlace.result.opening_hours.weekday_text.isNotEmpty() ){
println("The response for place time " + responsePlace.result.opening_hours.weekday_text[0].toString())}

you can try this :
responsePlace.let
{
when(it.isSuccessful) {
true -> println(""The response for place time " + it.result.opening_hours.weekday_text[0].toString()")
false -> println("something went wrong!")
}

Use the handy isNullOrEmpty() method in kotlin.
So your method will look like
if (!responsePlace.result.opening_hours.weekday_text.isNullOrEmpty()){
println("The response for place time " + responsePlace.result.opening_hours.weekday_text[0].toString())}
take care of the '!' negation at the start of the condition

You must check which object is null or better to post log trace.
you may use Kotlin safe call which will prevent NPE.
if(responsePlace?.result?.opening_hours.weekday_text.isNullOrEmpty())
println("The response for place time " + responsePlace.result.opening_hours.weekday_text[0].toString())

Related

Android DataBinding showing merged string with null check not working

I need to have show merged string through data binding. I can able to show it by below code easily.
android:text='#{sentRequestItems.receiver.firstName + " " + sentRequestItems.receiver.lastName}'
But in some case their is possibility that last name getting null form API response so in that case i can not able to show last name with null check.
I am trying with below code.
android:text='#{sentRequestItems.receiver.firstName != null ? sentRequestItems.receiver.firstName : "" + " " + sentRequestItems.receiver.lastName != null ? sentRequestItems.receiver.lastName : ""}'
Here with this it is not showing last name when it is not null in API response.
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/txvContactName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_marginStart="#dimen/_8sdp"
android:layout_marginEnd="#dimen/_4sdp"
android:layout_toStartOf="#+id/ivCancelRequest"
android:fontFamily="#font/lato_bold"
android:text='#{sentRequestItems.receiver.firstName != null ? sentRequestItems.receiver.firstName : "" + " " + sentRequestItems.receiver.lastName != null ? sentRequestItems.receiver.lastName : ""}'
android:textColor="#color/black"
android:textSize="#dimen/_15ssp"
tools:text="John Donny">
Any help is greatly appreciated.
I think it's not a best idea to perform coding in xml, readability suffers.
I suggest you to create static method, something like
class Utils {
static String formatName(RequestItem sentRequestItems) {
return (sentRequestItems.receiver.firstName != null ?
sentRequestItems.receiver.firstName : "") + " " +
(sentRequestItems.receiver.lastName != null ? sentRequestItems.receiver.lastName : "")
}
}
It's simplier to debug.
Also, don't forget brackets. You code doesn't work, because if first comparison sentRequestItems.receiver.firstName != null succeeds, all expression just returns sentRequestItems.receiver.firstName.
then in import it in your xml and use, like
android:text="#{Utils.formatName(sentRequestItems)}"
You can use BindingAdapter.
In Kotlin.
Step 1
Create a class BindingAdapters where you will have all your binding adapters method.
Step 2: Create a function like below
#BindingAdapter("app:contact_name")
#JvmStatic
fun setContactName(tvContactName: TextView, sentRequest: SentRequestItems?) {
if(sentRequest.receiver!=null){
if(sentRequest.receiver.lastName.isNullOrEmpty()){
tvContactName.text=sentRequest.receiver.firstName
}else{
tvContactName.text="$sentRequest.receiver.firstName
$sentRequest.receiver.firstName"
}
}
}
Step 3: Add the attribute in your text view
app:contact_name="#{sentRequestItems}"

How does subscribeOn work

I have some doubts regarding the working on the subscribeOn operator. I read some article regarding this.
The observeOn is quite easy to understand, it changes only the downstram, and change affects to all the downstream.
But as told in the article subscribeOn can be put in any place in the stream because it affects only the time of subscription.:
To understand this , I did a samlpe and tried logging the thread at each point of time.
Observable.just("Hello")
.map(s -> {
Log.d(TAG, s + " in " + Thread.currentThread());
return 1;
})
.subscribeOn(Schedulers.newThread())
.map(integer -> {
Log.d(TAG, integer + " in " + Thread.currentThread());
return true;
})
.map(aBoolean -> {
Log.d(TAG, aBoolean + " in " + Thread.currentThread());
return 11.0;
})
.subscribeOn(Schedulers.computation())
.subscribe(aDouble -> {
Log.d(TAG, "accept in " + Thread.currentThread());
Log.d(TAG, "accept: " + aDouble);
});
The result is
Hello in Thread[RxNewThreadScheduler-1,5,main]
1 in Thread[RxNewThreadScheduler-1,5,main]
true in Thread[RxNewThreadScheduler-1,5,main]
accept in Thread[RxNewThreadScheduler-1,5,main]
accept: 11.0
Here twice I'm applying subscribeOn, but everytime the first added one seem to be applied throughout the stream.
Can anyone please explain in simple words how does it actually work, since I'm a beginner and hard to digest this!
Thanks in advance
subscribeOn: If you have multiple subscribeOn then the first one takes effect. If you want to change the Scheduler on the stream after making a subscribeOn, then take a look at observeOn
observeOn: It changes the Scheduler going downstream.
For example:
just("Some String") // Computation
.subscribeOn(Schedulers.computation()) // it changes scheduler to computation beginning from source to observer.
.map(str -> str.length()) // Computation
.observeOn(Schedulers.io) //change the scheduler from here till the observer
.map(length -> 2 * length) // io
.subscribe(number -> Log.d("", "Number " + number));// io

equals method and single quote

I've this code:
gProvincia = "Reggio nell'Emilia";
if (gProvincia.equals(provincia.getProperty("provincia").toString()))
{
indiceSpinProv = x;
}
It seems that the single quote cause a problem to equals method, because setting gProvincia as Parma, equals return true when finds the same object in provincia.getProperty("provincia").
But this doesn't happen when the gProvince value contains a single quote.
I've also tried escaping the single quote with "\", without success.
Any suggestion?
Thanks!

Android: Currently Displayed Layout(s) file name(s)

How to get the name of the currently used Layout(s) file name(s) ?
for example it could be res/layout/main.xml or something like that.
Also, the code which require this information is not part of the app that contains this layout, it's kind of a testing code.
You don't. Internally Android doesn't refer to them by filenames, it refers to them by id- an integer. You can see the integer it uses in your generated R file. And that information isn't stored, it inflates the proper file then forgets about it.
i assume, you can go with reflection and lots of iteration.
First you want all your statics in the R.layout class - then you obtain their values and compare them to the View.getId() and in a last step you retrieve the fields name.
but: the name will only contain layout-files name (in your example main) and not the full path to it, even though you could have duplicate layouts with the same name, e.g. for landscape/portrait mode etc
I never tried something like that and I'm not sure if this works out, because i don't know if your testenvironment can access your R file without errors, but that's the way you could go
edit: just adding some sample code that should do the job, works from within the app - as said i'm unsure about your framework and the way you access r
R.layout layout = new R.layout();
Map<Integer, String> id2name = new HashMap<Integer, String>();
for (Field f : layout.getClass().getDeclaredFields()) {
try {
id2name.put(f.getInt(layout), f.getName());
Log.i("Layout", f.getInt(layout) + "," + f.getName());
}
catch (IllegalArgumentException e) {
//oops
Log.e("Layout", "", e);
}
catch (IllegalAccessException e) {
//oops
Log.e("Layout", "", e);
}
}
for (Entry<Integer, String> e:id2name.entrySet()) {
if (findViewById(e.getKey()) != null) {
Log.i("Layout:", "found: " + e.getValue() + ";" + e.getKey());
}else {
Log.i("Layout:", "not found: " + e.getValue()+ ";" + e.getKey());
}
}
note that there will be no view found unless layouting is done (findViewById() is null if you call to early)
of course you can go the other way around and search down the view tree by checking if a layout is instance of a ViewGroup and iterate over its childviews and compare each's id to the ids in the map

Program seems to be ignoring lines of code

I need help with this function.
I know that the if statement recognizes my input because it affects the program elsewhere, but I'm not sure what's going on because this particular Log doesn't display anything even in adb logcat.
Other Log statements in the same class file that this function is from display just fine, and the value update does seem to be changing ("show all" blanks it for some reason but I can figure that out after I get the log to work.)
I am unsure how to search for this problem because it is very specific and I have no idea what causes it (probably something simple that I didn't think of, though.)
void command(String input)
{
//do stuff here
//update = whatever
if(input.equalsIgnoreCase("show all"))
{
update=printAllRooms();
Log.i(input, update);
}
else update=input; //just for testing, will delete later
}
the printAllRooms function:
public String printAllRooms() //for debug purposes
{
String result = "";
for (Iterator<Room> iterator = rooms.iterator(); iterator.hasNext();) {
Room current = iterator.next();
result = result + current.toString()+"\n";
Log.i("printallrooms", current.toString());
}
return result;
}
A note on using Log.
The first argument sent to Log is typically a fixed string indicating the name of the class you are in.
So at the top of your class you might define:
private static final String TAG = "MyClassName";
Then you would use TAG for your log statements in that class.
Log.i(TAG, "My input was: " + input + " Update was: " + update;
To put it mildly, your function looks quite odd. Set a breakpoint at your Log statement, run the debugger and then inspect the variable value contained in update. Most likely, printAllRooms() is not doing what you think.
If the iterator doesn't work for you, try using the For-Each loop:
for (Room r : rooms) {
result = result + r.toString()+"\n";
Log.i("printallrooms", r.toString());
}

Categories

Resources