Roku Developer Program

Join our online forum to talk to Roku developers and fellow channel creators. Ask questions, share tips with the community, and find helpful resources.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
AKRDev
Reel Rookie

Changing the screen(s) content through API calls

Hi everyone,

I have been trying to develop a channel that has multiple "scenes/levels". I read a lot of documentations about Roku's tasks, scenes... but the more I read the more confused I get in understanding.

I want first screen to display shows, and once the user clicks ok, I want the content of the screen to change and display the show's seasons/episodes.

I managed to make the first API call through main.brs and display the shows on HomeScene's GridView once the app is launched.

And when I select one of the show's right now it goes to the next screen which is empty, I'm trying to get the season/episodes of that show to display in the same manner as in the first screen, To do that I need to make another API call, which I tried to do similar to the one in main.brs but it turned out to be a no no and had to create a "Task" file. Now my confusion is about linking the Task with the Season's scene for example.

I am thinking about doing the API call in the Task, return a JSON string to my scene and parse that JSON string to populate the Season's scene. Either that or parse the JSON inside the Task file.

I built it off of the Roku's sample video with description channel.

Any input would be great since I think I am misunderstanding the flow/structure of Tasks and Scenes

0 Kudos
6 REPLIES 6
speechles
Roku Guru

Re: Changing the screen(s) content through API calls


@AKRDev wrote:

I am thinking about doing the API call in the Task, return a JSON string to my scene and parse that JSON string to populate the Season's scene. Either that or parse the JSON inside the Task file.

Definitely want to always be thinking that. Render task does render things. Other things go in their own task. Use observers and fields.

 

You need to show some code or what exactly you are trying to do without showing all your code. Give some code examples you are using and how you are implement them. What does your onKeyEvent look like? Do you have one? What do you mean in main? You use main to contact scene with a field and observer? I am surely not following nor can likely anyone else.

 

You are using the main to pass events to the scene? with fields and observers? Using alwaysNotify with an onChange handler? Can you explain a little better and break it down for us with some code examples. It would make it less head-wrapping to help. 

 

 

You want to make the task fetch your api request and then parse the json into an associate array. The task also has to return that associative array to your scene. The task should also use a field called isCompleted to signal to the scene when it has finished so the scene can stop displaying "loading..." or whatever it does for interstitial moments of loading.

0 Kudos
AKRDev
Reel Rookie

Re: Changing the screen(s) content through API calls

Thanks for the reply, @speechles! Between then and now I was able to get the task to do the API call properly.

My Task.xml

<?xml version="1.0" encoding="utf-8" ?>
<component name="GetSeason" extends="Task">
  <interface>
    <field id = "contenturi" type = "string" />
    <field id = "content" type = "assocarray" />
  </interface>
  <script type="text/brightscript">
    
  <![CDATA[
  
  	sub init()
  		m.top.functionName = "getAPIResponse"
  	end sub
  	
  	sub getAPIResponse()  	
  	        port = CreateObject("roMessagePort")
    	        request = CreateObject("roUrlTransfer")
    	        request.setRequest("GET")
         	request.setURL(contenturi)
        	jsonString = request.GetToString()
        	jsonParsed = ParseJson(jsonString)
                m.top.content = jsonParsed    
  	end sub
  ]]> 
  </script>
</component>

m.top.content seems to have the correct value from the returned JSON.

 

Now the issue I'm facing is how to get that JSON back into my Scene.brs file? And then display it on a RowList item

 

in my Scene.brs

    m.sceneTask.control = "RUN"
    jsonTest = m.top.content

Now I want the jsonTest to have the value of m.top.content from the Task.xml, when I do the above, the value of jsonTest is roInvalid

0 Kudos
AKRDev
Reel Rookie

Re: Changing the screen(s) content through API calls

I believe getting the value back to Scene.brs works now. The code above was missing an observer. Once set, now my json object is passed back to the Scene.brs as I wanted it with the correct value.

However, my observer function can set the value properly inside the function itself, but I still cannot assign that value to the jsonTest in the other function. 

 

On my brs file I have this

    m.sceneTask.observeField("content","gotContent")
    m.sceneTask.control = "RUN"

   jsonThatIWantToUse = .... <---- I want this to have the m.sceneTask.content value

Then

sub gotContent()
    jsonReturned = m.sceneTask.content <-- this has the correct value
end sub

 

0 Kudos
KiranPrasanna
Channel Surfer

Re: Changing the screen(s) content through API calls


Hello,

I am running this file in task.xml

<?xml version=“1.0” encoding=“utf-8" ?>
<!-- Copyright 2016 Roku Corp. All Rights Reserved. -->
<component name=“ContentReader” extends=“Task”>
<script type=“text/brightscript”>
<![CDATA[
sub init()
m.top.functionName = “getAPIResponse”
end sub

sub getAPIResponse()
port = CreateObject(“roMessagePort”)
request = CreateObject(“roUrlTransfer”)
request.setRequest(“GET”)
request.setURL(m.top.contenturi)
jsonString = request.GetToString()
jsonParsed = ParseJson(jsonString)
m.top.content = jsonParsed
end sub
]]>
</script>
</component>

And Used this below function in main.brs file

sub Main()
print “in showChannelSGScreen”
m.readXMLContentTask = createObject(“roSGNode”, “ContentReader”)
m.readXMLContentTask.observeField(“content”, “setcontent”)
m.readXMLContentTask.contenturi = “http://www.sdktestinglab.com/Tutorial/content/xmlcontent.xml”
m.readXMLContentTask.control = “RUN”
readData = m.top.content
print “readData”
end sub

but this function is not executed in main.brs file
Can you please help me to execute this function from main.brs Or provide the sample examples

0 Kudos
KiranPrasanna
Channel Surfer

Re: Changing the screen(s) content through API calls

Hello,

I am running this file in task.xml

<?xml version="1.0" encoding="utf-8" ?>
<component name="GetSeason" extends="Task">
<interface>
<field id = "contenturi" type = "string" />
<field id = "content" type = "assocarray" />
</interface>
<script type="text/brightscript">

<![CDATA[

sub init()
m.top.functionName = "getAPIResponse"
end sub

sub getAPIResponse()
port = CreateObject("roMessagePort")
request = CreateObject("roUrlTransfer")
request.setRequest("GET")
request.setURL(contenturi)
jsonString = request.GetToString()
jsonParsed = ParseJson(jsonString)
m.top.content = jsonParsed
end sub
]]>
</script>
</component>

And Used this below function in main.brs file

sub init()
m.sceneTask.observeField("content","gotContent")
m.sceneTask.control = "RUN"
end sub

sub gotContent()
jsonReturned = m.sceneTask.content
end sub

but this function is not executed in main.brs file
Can you please help me to execute this function from main.brs Or provide the sample examples

0 Kudos
NicholasStokes
Binge Watcher

Re: Changing the screen(s) content through API calls

Hello,I am running this file in task.xml<component name = "ContentReader" extends = “Task” >  <interface>
    <field id = "contenturi" type = "uri" />
    <field id = “content” type = “node” />
  </interface>  <script type = “text/brightscript” >    <![CDATA[    sub init()
      m.top.functionName = “getcontent”
    end sub    sub getcontent()
      content = createObject(“roSGNode”, “ContentNode”)      contentxml = createObject(“roXMLElement”)      readInternet = createObject(“roUrlTransfer”)
      readInternet.setUrl(m.top.contenturi)
      contentxml.parse(readInternet.GetToString())      if contentxml.getName()=“Content”
        for each item in contentxml.GetNamedElements(“item”)
          itemcontent = content.createChild(“ContentNode”)
          itemcontent.setFields(item.getAttributes())
        end for
      end if      m.top.content = content
    end sub    ]]>  </script></component>And Used this below function in main.brs filesub init()  m.readXMLContentTask = createObject(“roSGNode”, “ContentReader”)
  m.readXMLContentTask.observeField(“content”, “setcontent”)
  m.readXMLContentTask.contenturi = “http://www.sdktestinglab.com/Tutorial/content/xmlcontent.xml
  m.readXMLContentTask.control = “RUN”
end subsub setcontent()
  m.content = m.readXMLContentTask.content
  m.contentitems = m.content.getChildCount()
  m.currentitem = 0end subbut this function is not executed in main.brs file
Can you please help me to execute this function from main.brs Or provide the sample examples

0 Kudos