Kotlin: Unresolved reference: use,

683 Views Asked by At

I am trying to integrate a Dialogflow Agent with Pepper: https://developer.softbankrobotics.com/pepper-qisdk/lessons/integrating-chatbot-dialogflow

I followed all the steps until the Testing your agent in standalone section, where I have to add the following Kotlin code to the DialogflowSource class:

import com.google.auth.oauth2.ServiceAccountCredentials
import com.google.cloud.dialogflow.v2.*
import java.io.InputStream

class DialogflowDataSource constructor(credentialsStream : InputStream) {
   private val credentials : ServiceAccountCredentials
       = ServiceAccountCredentials.fromStream(credentialsStream)

   fun detectIntentTexts(
       text: String,
       sessionId: String,
       languageCode: String
   ): String? {
       val sessionsSettings = SessionsSettings.newBuilder()
           .setCredentialsProvider(FixedCredentialsProvider.create(credentials))
           .build()
       SessionsClient.create(sessionsSettings).use { sessionsClient ->    //Error: Unresolved reference for .use
           val session = SessionName.of(credentials.projectId, sessionId)
           val textInput = TextInput.newBuilder()
               .setText(text).setLanguageCode(languageCode)
           val queryInput = QueryInput
               .newBuilder().setText(textInput).build()
           val response = sessionsClient.detectIntent(session, queryInput)
           return response.queryResult.fulfillmentText
       }
   }         //Error: A 'return' expression required in a function with a block body ('{...}')
}

I'm new to Kotlin, so I don't really know how to fix this. Any help would be appreciated!

1

There are 1 best solutions below

1
On

First, why would you use use? It seems you meant to call apply instead. But in fact you could just write:

fun detectIntentTexts(
       text: String,
       sessionId: String,
       languageCode: String
   ): String? {

   val sessionsSettings = SessionsSettings.newBuilder()
       .setCredentialsProvider(FixedCredentialsProvider.create(credentials))
       .build()
    val sessionClient = SessionsClient.create(sessionsSettings)
    val session = SessionName.of(credentials.projectId, sessionId)
    val textInput = 
        TextInput.newBuilder().setText(text).setLanguageCode(languageCode)
    val queryInput = QueryInput.newBuilder().setText(textInput).build()
    val response = sessionsClient.detectIntent(session, queryInput)
    return response.queryResult.fulfillmentText
}

But if you care using use (or apply), the lambda you provide to it should not directly make the outer function detectIntentTexts return. Instead, let your lambda return its result locally, and let detectIntentTexts return it:

   fun detectIntentTexts(
       text: String,
       sessionId: String,
       languageCode: String
   ): String? {
       val sessionsSettings = SessionsSettings.newBuilder()
           .setCredentialsProvider(FixedCredentialsProvider.create(credentials))
           .build()
       return SessionsClient.create(sessionsSettings).apply { sessionsClient ->
           val session = SessionName.of(credentials.projectId, sessionId)
           val textInput = TextInput.newBuilder()
               .setText(text).setLanguageCode(languageCode)
           val queryInput = QueryInput
               .newBuilder().setText(textInput).build()
           val response = sessionsClient.detectIntent(session, queryInput)
           response.queryResult.fulfillmentText
       }
   }
}