Bixby: page might be empty warnings - bixby

I'm really stuck and don't know what to do.
I've never worked in Bixby Studio and got that warning "page might be empty".
I've seen two similar posts about this problem, but they didn't help me at all.
item-selection-question {
first warning--> if (isFirstNavPage(page) && isLastNavPage(page)) {
template ("")
second warning--> } else-if (!isLastNavPage(page)) {
template-macro (HANDS_FREE_OPTION_ITEM_SELECTION_MORE_PAGES)
} else {
template-macro (HANDS_FREE_OPTION_ITEM_SELECTION_LAST_PAGES)
}
}
overflow-statement {
template-macro (HANDS_FREE_OPTION_OVERFLOW_STATEMENT)
}
overflow-question {
template-macro (HANDS_FREE_OPTION_OVERFLOW_QUESTION)
}
page-marker {
third warning--> if (!isFirstNavPage(page) && isLastNavPage(page)) {
template-macro (HANDS_FREE_OPTION_LAST_OPTION) {
param (page) {
expression (page)
}
}
}
}

I had a similar warning for,
content {
template ("Here's #{value(audioInfo.audioItem[audioInfo.startAudioItemIndex].artist)}.") {
speech ("Here's #{value(audioInfo.audioItem[audioInfo.startAudioItemIndex].title)}[ from #{value(audioInfo.audioItem[audioInfo.startAudioItemIndex].artist)}].")
}
}
WARN audioInfo.startAudioItemIndex might be empty
I changed the above snippet to,
content {
if(exists(audioInfo.startAudioItemIndex)){
template ("Here's #{value(audioInfo.audioItem[audioInfo.startAudioItemIndex].artist)}.") {
speech ("Here's #{value(audioInfo.audioItem[audioInfo.startAudioItemIndex].title)}[ from #{value(audioInfo.audioItem[audioInfo.startAudioItemIndex].artist)}].")
}
}
}
And it no longer shows the warning.
Try and see if it helps.

Related

How to conditional statements in action output in Bixby

Hi I want to go to another action by putting a conditional statement in the action output.
What should I do?
For example
action (~~) {
description (Validate items passed from javascript)
collect {
input (~~) {
type (~~)
min (~~) max (~~)
}
}
type(~~~)
output (items){
on-empty(items.item1){ // if items.item1 is empty.
replan { // go to case1Action.
intent {
goal : case1Action
value : ~~~~~
}
}
}else{ // else
replan { // go to case2Action.
intent {
goal : case2Action
value : ~~~~~
}
}
}
}
or I want to select the view according to the output value.(Actually this is the purpose of the question)
output (items){
if(items.item1 == "goFirstCase"){
// First case view
}else{
// Second case view
}
}
I think by "select a different view according to the output value" I presume you mean you want to change what shows on the screen? because a "view" actually is comprised of the dialog, layout, and conversation-drivers.
https://bixbydevelopers.com/dev/docs/dev-guide/developers/building-views.views
For majority of use cases, there's really only one result-view that will be used, and any of the three contents of a view can be changed based on your preferred conditions as the above answer suggests.
within a view you can have the three different components defined with these three blocks: message for dialog, render for layout, and conversation-drivers
using your example,
//in a result-view
message {
if (items.item1 == "firstCase") {
template-macro (firstCase-result-dialog) {//enter params}
}
}
render {
if (size(items) > 1) {
list-of (items) {
where-each (item) {
if (item == "firstCase") {
layout-match (item) {
mode (Summary)
}
// OR use layout-macro
layout-macro (firstCase-result-summary-thumbnail-card) {//enter params}
}
}
}
}
}
similar conditional work can be done on conversation-drivers of course.
In your case, you would not need on-empty in action, but use template-macro-def as briefly explained in https://corp.bixbydevelopers.com/dev/docs/dev-guide/developers/refining-dialog.dialog-macros
// template file one
template-macro-def (id1) {
params {
param (x) {
Type (Items) ....
}
// template file two
template-macro-def (id2) {
// param x is type Items
}
//view file
result-view {
match: Items(this)
// after some checking make sure is single item
// it is possible to use other condition like if (this.sub1 == 2)
if (exists(this.sub1)) {
template-macro (id1) {
param (x) { expression (this) }
}
}
else {
template-macro (id2) {
param (x) { expression (this) }
}
}
The above would be the recommended way to handle different views for same concept in Bixby.
on-empty in action would be used for the purpose of either replan or relax some search condition in order to avoid 0 result. Bixby does not support on-empty(key) {} syntax according to https://corp.bixbydevelopers.com/dev/docs/reference/type/action.output.on-empty and on-empty would only apply in your case if output(items) itself is empty and would not check any sub-property of items.
Another option.
instead to use 'on-empty' block, you can use 'throws - error'
in action model,
output (items) {
throws {
error (case1ActionError) {
on-catch {
replan {
intent {
goal : case1Action
value : ~~~~~
}
}
}
}
error (case2ActionError) {
on-catch {
replan {
intent {
goal : case2Action
value : ~~~~~
}
}
}
}
}
}
And, in js code,,
if (error condition1) {
throw fail.checkedError('case 1 error', 'case1ActionError')
} else if (error condition2) {
throw fail.checkedError('case 2 error', 'case2ActionError')
}
For fail, refer to https://bixbydevelopers.com/dev/docs/reference/JavaScriptAPI/fail#failcheckederrormessage-errorid-errorobj

how to insert layout macro above thumbnail

I want to insert tiny type above the answer set providing a bit of metadata, but can't figure out how to do it. I just want the layout macro content-answer-set-info to say something like "results in reverse chronological order" in Legal or Detail_S. I want it to appear below altbrains workshop and above the first item in the list.
render {
if (size(this) > 1) {
list-of (this) {
has-details (true)
where-each (item) {
layout-macro (content-thumbnail-card) {
param (content) {
expression (item)
}
}
}
}
}
else-if (size(this) == 1) {
layout-match (this) {
mode (Details)
}
}
else {layout-macro (content-zero-results) {}
}
I would recommend wrapping this layout macro in a section and using the section-title (documentation) key to give it the text above the list.
There is an alternative solution that use section -> title but not with list-of
render {
layout {
section {
title {
template ("Voice command Add One")
}
content {
for-each (this) {
as (item) {
title-card {
title-area {
slot2 {
single-line {
text {
value {
template ("Integer: #{value(item.number)}")
}
style (Detail_L)
}
}
}
}
}
}
}
}
}
}

How to handle zero search result scenarios

What are some good examples of different ways to handle zero result search answer sets in result views?
Here's what I have right now. I assume I want to do size(this) < 1 but before I plunge ahead I want some ideas about what to do. For example, should I just say "search again" or should I try to recommend something to do?
render {
if (size(this) > 1) {
list-of (this) {
//default-sort-order {
// sorting(this.title)
// }
has-details (true)
where-each (item) {
layout-macro (content-thumbnail-card) {
param (content) {
expression (item)
}
}
}
}
} else-if (size(this) == 1) {
layout-match (this) {
mode (Details)
}
}
}
There is a NoResult dialog that will automatically activate for this condition:
https://bixbydevelopers.com/dev/docs/reference/ref-topics/dialog-modes.dialog-events#no-result-event
You can also place a conditional in your result view. For example:
result-view {
match: SomeConcept(this)
message {
if (size(this) == 0) {
template (No results)
}
}
render {
layout {
section {
content {
// No Result
if (size(this)== 0) {
paragraph(Sorry, I didn't find anything)
}
}
}
}
}
}

Can you refresh an input-view?

I am trying to create an input-view that will refresh every few seconds. The goal is to have a few buttons that increment and the user will click on the buttons when the buttons reach a 100. However, it seems like the action is waiting for an input so it is not updating. I found on the documentation that you can refresh an input-view, but I can't find any examples of it.
This is the code that I want to update:
input-view{
match: State(state){
to-input: UpdateGame
}
message{
template ("#{value(state.display)}"){
speech ("#{value(state.say)}")
}
}
refresh{
spec{
delay-seconds (2)
with-request{
intent{
goal: UpdateGame
}
}
}
}
render{
selection-of (state.options){
where-each (option){
cell-card{
slot2{
content{
primary{
template ("#{value(option)}")
}
}
}
}
}
}
}
}
There is one example of result-view in this doc
result-view {
match {
Activity (this)
}
refresh {
if (!exists(this.receipt)) {
spec {
delay-seconds (5)
with-request {
intent {
goal: CheckRideShareStatus
value {$expr(this)}
}
}
}
}
}
conversation-drivers {
if ("this.status == 'Requested' || this.status == 'Confirmed'") {
conversation-driver {
template ("Cancel my Uber ride")
}
}
}
render {
layout-match (this) {
mode (Details)
}
}
}
Sorry I've not caught this question earlier.
I've just verified that this issue is fixed in 20B SDK release.
Please refer the release notes for details about other changes.

How do I get rid of all the "Warn this.name might be empty" warnings?

In my Cat.view.bxb file, I have some UI elements that are based on optional properties in the structure that have warnings attached to them.
WARN this.name might be empty
result-view{
match {
Cat (this)
}
render {
layout {
section {
content {
paragraph {
style (Title_XS)
value ("#{value(this.name)}")
}
}
}
}
}
}
The warnings serve to remind you that the UI elements you've defined will not be displayed if the optional properties are not present.
You should define an if(exists(this.name)) and define UI elements for when the optional elements are not available.
For example, your code would look something like the following:
result-view{
match {
Cat (this)
}
render {
layout {
section {
content {
if(exists(this.name)) {
paragraph {
style (Title_XS)
value ("#{value(this.name)}")
}
} else {
paragraph {
style (Title_XS)
value("No name!")
}
}
}
}
}
}
}
By doing so, you are addressing the root cause of the warning and creating a more responsive output for your users.
if (exists) works and is one way as articulated already and provides excellent context for the user. Another way that may be preferable in certain circumstances is to use the [] square brackets notation - if a section within square brackets renders null then the section is skipped. So for your example:
result-view{
match {
Cat (this)
}
render {
layout {
section {
content {
paragraph {
style (Title_XS)
value ("[#{value(this.name)}]")
}
}
}
}
}
}

Resources