Loop through a content node

guys, could you please give me an example how to loop through a content node?

lets say i create a regular content node, and i populate it programatically from the information in my server.

now I had a json and did a task to form the content node and got it back from my task, but now i want to loop in scenegraph thread, how could i do that?

ContentNode is designed as a “vessel” for a Roku multimedia item (one video, one audio etc). It is just a Node with extra data junk (i.e. fields) shoved into it. Use ContentNode only when

  1. a RSG component demands one or

  2. your data is well-described by https://sdkdocs.roku.com/display/sdkdoc/Content+Meta-Data

If you have a collection of e.g. videos, you should use a Node as container - or roAA, depending on threading concerns.
Be more specific - what is your case?

“EnTerr” wrote:
ContentNode is designed as a “vessel” for a Roku multimedia item (one video, one audio etc). It is just a Node with extra data junk (i.e. fields) shoved into it. Use ContentNode only when

If you have a collection of e.g. videos, you should use a Node as container - or roAA, depending on threading concerns.
Be more specific - what is your case?
Thanks for answering I kept trying and got to loop through a content node. Just to complete my post and give out the answer i was looking for this..

sub setEpg()
    print "setting up content"
    m.channel = m.liveTvJsonReaderTask.getField("content")
    i = 0
    while i < m.channel.getChildCount()
        print "m.channel.getChild(i)", m.channel.getChild(i)
        print "m.channel.getChild(i).TITLE:", m.channel.getChild(i).TITLE
        i = i + 1
    end while
end sub

Oh, that. Then you can as well do

channels = m.liveTvJsonReaderTask.content.getChildren(1e4, 0)
for each channel in channels:
  print channel.title, channel
next

or more convolutedly

channelNoid = m.liveTvJsonReaderTask.content
for i = 0 to channelNoid.getChildCount()-1:
  channel = channelNoid.getChild(i)
  print channel.title, channel
next

Word has it that in coming version of RSG you could just use a roArray-type field instead of doing this whole gallimaufry (using Node as array-alike container).

“EnTerr” wrote:
Oh, that. Then you can as well do

channels = m.liveTvJsonReaderTask.content.getChildren(1e4, 0)
for each channel in channels:
  print channel.title, channel
next

or more convolutedly

channelNoid = m.liveTvJsonReaderTask.content
for i = 0 to channelNoid.getChildCount()-1:
  channel = channelNoid.getChild(i)
  print channel.title, channel
next

Word has it that in coming version of RSG you could just use a roArray-type field instead of doing this whole gallimaufry (using Node as array-alike container).
It would be great to have an interfase that returns roassociativearray with more roassociativearrays inside. Or just a dynamic format hahah
But yeah im using the content node as an array since thats what i found i could use..

“adrianc1982” wrote:
It would be great to have an interfase that returns roassociativearray with more roassociativearrays inside.
You already have that, you can do roAssociativeArray of… anything, really. What you don’t have is <roArray of anything>. Because… RSG creator’s vision (“think different, not necessarily better”):

' you cant have this: '
myNode.addFields({ myField: [1, 2, 3] })

' however, you can cheat and do this just fine: '
myNode.addFields({ myField: {bless_RSGs_maker: [1, 2, 3]} })

Or just a dynamic format hahah
But yeah im using the content node as an array since thats what i found i could use..
Here is me struggling with the same earlier https://forums.roku.com/viewtopic.php?f=34&t=96382

“EnTerr” wrote:

“adrianc1982” wrote:
It would be great to have an interfase that returns roassociativearray with more roassociativearrays inside.
You already have that, you can do roAssociativeArray of… anything, really. What you don’t have is <roArray of anything>. Because… RSG creator’s vision (“think different, not necessarily better”):

' you cant have this: '
myNode.addFields({ myField: [1, 2, 3] })

' however, you can cheat and do this just fine: '
myNode.addFields({ myField: {bless_RSGs_maker: [1, 2, 3]} })

Or just a dynamic format hahah
But yeah im using the content node as an array since thats what i found i could use..
Here is me struggling with the same earlier https://forums.roku.com/viewtopic.php?f=34&t=96382
Just read this answer before posting in your thread, im new to RSG so i havent had the chance to or flight hours to discover this. I really have always thought of roku development as hacky because of all the cheating you have to do. Thank you so much for the heads up even though this is not what we should be doing!

“adrianc1982” wrote:
Just read this answer before posting in your thread, im new to RSG so i havent had the chance to or flight hours to discover this. I really have always thought of roku development as hacky because of all the cheating you have to do. Thank you so much for the heads up even though this is not what we should be doing!
Correct, coding for Roku is very hacky. Some of the hacks are really beautiful and useful, others - not so much. The RSG in particular will make you wonder “man, they must sell some really strong ganja in those California pot dispensaries!”

“EnTerr” wrote:

“adrianc1982” wrote:
Just read this answer before posting in your thread, im new to RSG so i havent had the chance to or flight hours to discover this. I really have always thought of roku development as hacky because of all the cheating you have to do. Thank you so much for the heads up even though this is not what we should be doing!
Correct, coding for Roku is very hacky. Some of the hacks are really beautiful and useful, others - not so much. The RSG in particular will make you wonder “man, they must sell some really strong ganja in those California pot dispensaries!”
yeah i’ve loved some of the hacks back in brightscript, im trying to code myself into RSG but my old channel is over 6000 lines of code, its not that easy.. heheh but im 30% done give or take. I hope i get to understand RSG more and more by the time im 100% done with my channel. I really do feel like a developer discovering all this cheats and hacks and seeing all that speed with something I shouldnt be using. Thank you for your answers its always a delight to read them and i apologize for my broken english, i try my best just to keep up with you :slightly_smiling_face:

“EnTerr” wrote:

“adrianc1982” wrote:
It would be great to have an interfase that returns roassociativearray with more roassociativearrays inside.
You already have that, you can do roAssociativeArray of… anything, really. What you don’t have is <roArray of anything>. Because… RSG creator’s vision (“think different, not necessarily better”):

' you cant have this: '
myNode.addFields({ myField: [1, 2, 3] })

' however, you can cheat and do this just fine: '
myNode.addFields({ myField: {bless_RSGs_maker: [1, 2, 3]} })

Or just a dynamic format hahah
But yeah im using the content node as an array since thats what i found i could use..
Here is me struggling with the same earlier https://forums.roku.com/viewtopic.php?f=34&t=96382
En Terr
I do believe I understand the myNode.addFields({ myField: {bless_RSGs_maker: [1, 2, 3]} }) but I am having some trouble. Just before my Task finish up, I have the following

Content = CreateObject("roSGNode", "ContentNode")
for each item in result
?item
data=Content.createChild("ContentNode")
data.addfields({"resultfield": {info: [item]}})
end for
?data
m.top.content=Content

I may not understand as much as I think, I know my loop above creates roassociativearray with all the info in the result. The ?data shows all teh resultfields as being roassociativearray. When I get back into the bs code, I am using something like

data=m.ContentTaskp.getChildren(1e4, 0)
for each item in data
?item
end for

Apparently I am missing a step, if I type(data) it shows to be roArray but all empty. Can you point out the missing step. Thanks for any help

btpoole -
there are pieces of info missing in your explanation, so i would have to guess.

m.top.content = Content

m.top is the Task? does it have a field “content” declared in the interface? put a debug “? m.top.content” right after it to see if value got stored.

data = m.ContentTaskp.getChildren(1e4, 0)

aren’t you missing “.content.”? as in “m.ContentTaskp.content.getChildren(”

“EnTerr” wrote:
btpoole -
there are pieces of info missing in your explanation, so i would have to guess.

m.top.content = Content

m.top is the Task? does it have a field “content” declared in the interface? put a debug “? m.top.content” right after it to see if value got stored.

data = m.ContentTaskp.getChildren(1e4, 0)

aren’t you missing “.content.”? as in “m.ContentTaskp.content.getChildren(”
You are correct. I guess it’s a case of the forest, some trees and the view being obscured. I will add the content and see if that gets me closer. Thanks again

“EnTerr” wrote:
btpoole -
there are pieces of info missing in your explanation, so i would have to guess.

m.top.content = Content

m.top is the Task? does it have a field “content” declared in the interface? put a debug “? m.top.content” right after it to see if value got stored.

data = m.ContentTaskp.getChildren(1e4, 0)

aren’t you missing “.content.”? as in “m.ContentTaskp.content.getChildren(”
What if the m.top.content=Content is not showing the values? I have noticed this happening in past where ?data (in this case) shows the values but the m.top.content does not, like the Content is not wrapping the data into the contentnode.

“btpoole” wrote:
What if the m.top.content=Content is not showing the values? I have noticed this happening in past where ?data (in this case) shows the values but the m.top.content does not, like the Content is not wrapping the data into the contentnode.
It would mean the assignment “did not work”, one example would be if the field has not been declared (or dynamically added) in advance. You’d think that will cause runtime error, assigning to a non-existent field? Good thinking but no - there is a bug in RSG, in which it silently ignores such assignments without complaining…

“EnTerr” wrote:

“btpoole” wrote:
What if the m.top.content=Content is not showing the values? I have noticed this happening in past where ?data (in this case) shows the values but the m.top.content does not, like the Content is not wrapping the data into the contentnode.
It would mean the assignment “did not work”, one example would be if the field has not been declared (or dynamically added) in advance. You’d think that will cause runtime error, assigning to a non-existent field? Good thinking but no - there is a bug in RSG, in which it silently ignores such assignments without complaining…
I have noticed that, no errors and no data returned. I wasn’t sure if I was using addfields correctly for the associative array, but as I stated if I ?data, shows it to be correct but sometimes the content will not contain anything. Wish you could just pass the array back to the bs that created the task but from what I can tell that’s not possible or am I not understanding. The way I understand it, the bs uses the task to do everything I once done in a function and created the array, now the info is stored in a contentnode and the bs reads the contentnode.

“EnTerr” wrote:

“btpoole” wrote:
What if the m.top.content=Content is not showing the values? I have noticed this happening in past where ?data (in this case) shows the values but the m.top.content does not, like the Content is not wrapping the data into the contentnode.
It would mean the assignment “did not work”, one example would be if the field has not been declared (or dynamically added) in advance. You’d think that will cause runtime error, assigning to a non-existent field? Good thinking but no - there is a bug in RSG, in which it silently ignores such assignments without complaining…
As far as setting Content to m.top.content and it not assigning I have discovered something you probably and others know. In the following example I create an array like always and use addfields to assign it to the content. The content never accepted the field. So, instead of m.top.content=content I replaced with m.top.content=data. Data being the child I had hoped content would wrap and add to contentnode. When executed, the data has the resultfield but content never does.

Content = CreateObject("roSGNode", "ContentNode")
for each item in result
data=Content.createChild("ContentNode")
data.addfields( { resultfield: {result:[item] } } )
end for
?data           <<<<<<<<<<<  ACCEPTS FIELD resultfield
?CONTENT        <<<<<<<<<<<< NEVER WRAPS data
m.top.content=data

Once the above executes and returns to the brs I have the following

sub setGridcontent()
?"in setGridcontent"
data=m.ContentTaskp.content
?data
end sub

When this executes, the ?data displays the following
<Component: roSGNode> =
{
metadata: <Component: roContentMetadata>
change: <Component: roAssociativeArray>
focusable: false
focusedChild: <Component: roInvalid>
id:
resultfield: <Component: roAssociativeArray> <<<<< RESULTFIELD is part of the contentnode
}
How can I get into the resultfield? Have tried to set data=m.ContentTaskp.content.getChildren(1e4, 0) and run a loop but no luck, returns an empty roArray. Is resultfield not a child of the node?

“btpoole” wrote:

sub setGridcontent()
?"in setGridcontent"
data=m.ContentTaskp.content
?data
end sub

When this executes, the ?data displays the following

Sorry, i have to admit i couldn’t quite follow your explanation - seems to me parts are missing and it’s really hard to decode everything when there is no single piece of code.

This said, i will take a guess on the above: given that m.ContentTaskp.content in setGridContent() prints what you showed, you should be able to find the array you stored in m.ContentTaskp.content.resultfield.result. Did it have to be that complicated - probably not but that’s where it seems you put it.

And no - node fields are different from node children, so can’t enumerate them like so. That’s conceptually close to HTML, if you consider the nested html tags as “children” and a tag’s attributes as “fields”.

“EnTerr” wrote:

“btpoole” wrote:

sub setGridcontent()
?"in setGridcontent"
data=m.ContentTaskp.content
?data
end sub

When this executes, the ?data displays the following

Sorry, i have to admit i couldn’t quite follow your explanation - seems to me parts are missing and it’s really hard to decode everything when there is no single piece of code.

This said, i will take a guess on the above: given that m.ContentTaskp.content in setGridContent() prints what you showed, you should be able to find the array you stored in m.ContentTaskp.content.resultfield.result. Did it have to be that complicated - probably not but that’s where it seems you put it.

And no - node fields are different from node children, so can’t enumerate them like so. That’s conceptually close to HTML, if you consider the nested html tags as “children” and a tag’s attributes as “fields”.
I was able to locate the result. What I was mostly concerned with was that in the Task where m.top.content=content doesn’t work. The content being content=createobject(“rsgnode”, “ContentNode”). The content never incorporates the added fields. Looking back into what I posted

data=content.createchild("ContentNode")
data.addfields( { resultfield: {result:[item] } } )

the content doesn’t take in the data, so I set m.top.content=data and it worked. I was under the impression that you create a node (content in this case), then contentnode (data in this case) and then addfields to data. The data would be taken in by the content. At least this is something like I had done in another Task.
As for the location of result I was trying to follow the example you had posted , using resultfield and result.

myNode.addFields({ myField: {bless_RSGs_maker: [1, 2, 3]} })

Well, not sure why the data is not added to the content. Thanks for your advice and guidance thru out you have been most helpful to me many times on the forum.

“btpoole” wrote:
What I was mostly concerned with was that in the Task where m.top.content=content doesn’t work. The content being content=createobject(“rsgnode”, “ContentNode”). The content never incorporates the added fields. Looking back into what I posted

data=content.createchild("ContentNode")
data.addfields( { resultfield: {result:[item] } } )

the content doesn’t take in the data, so I set m.top.content=data and it worked. I was under the impression that you create a node (content in this case), then contentnode (data in this case) and then addfields to data. The data would be taken in by the content. At least this is something like I had done in another Task.

Well, not sure why the data is not added to the content. Thanks for your advice and guidance thru out you have been most helpful to me many times on the forum.
I have no idea what “m.top.content” is supposed to be in your Task, because you have not posted example. It is really, really frustrating to work like that and i will stop. Next time make small and very clear example that contains 100% of the relevant code. Not something to guess. Also see if you can use the “free Roku clinic” chat room - doing it interactively should be less frustrating than trying to read mind from a distance.

The child node is getting added to the parent. Perhaps you are confused about what createChild() does - it creates a new ContentNode and attaches it as a child to “content” (whatever is there, i have no idea, i assume some Node subclass). That does NOT however create any field for it, so you cannot find data inside content by indexing like content.data. Instead you should be using one of the https://sdkdocs.roku.com/display/sdkdoc … deChildren methods to find it later. What i said about HTML/XML analogy, you are creating something like this (make-believe, if it helps your thinking):

<node>
  <contentNode resultField="{result: [item]}">
  </contentNode>
</node>

“EnTerr” wrote:

“btpoole” wrote:
What I was mostly concerned with was that in the Task where m.top.content=content doesn’t work. The content being content=createobject(“rsgnode”, “ContentNode”). The content never incorporates the added fields. Looking back into what I posted

data=content.createchild("ContentNode")
data.addfields( { resultfield: {result:[item] } } )

the content doesn’t take in the data, so I set m.top.content=data and it worked. I was under the impression that you create a node (content in this case), then contentnode (data in this case) and then addfields to data. The data would be taken in by the content. At least this is something like I had done in another Task.

Well, not sure why the data is not added to the content. Thanks for your advice and guidance thru out you have been most helpful to me many times on the forum.
I have no idea what “m.top.content” is supposed to be in your Task, because you have not posted example. It is really, really frustrating to work like that and i will stop. Next time make small and very clear example that contains 100% of the relevant code. Not something to guess. Also see if you can use the “free Roku clinic” chat room - doing it interactively should be less frustrating than trying to read mind from a distance.

The child node is getting added to the parent. Perhaps you are confused about what createChild() does - it creates a new ContentNode and attaches it as a child to “content” (whatever is there, i have no idea, i assume some Node subclass). That does NOT however create any field for it, so you cannot find data inside content by indexing like content.data. Instead you should be using one of the https://sdkdocs.roku.com/display/sdkdoc … deChildren methods to find it later. What i said about HTML/XML analogy, you are creating something like this (make-believe, if it helps your thinking):


Thanks again, I do understand the xml analogy. As for the m.top.content=content, I posted this info in the original part of the post

Content = CreateObject("roSGNode", "ContentNode")
for each item in result
data=Content.createChild("ContentNode")
data.addfields( { resultfield: {result:[item] } } )                                 <<<<<<<<<<data is not created as child of of ContentNode
end for
?data           <<<<<<<<<<<  ACCEPTS FIELD resultfield
?CONTENT        <<<<<<<<<<<< NEVER WRAPS data
m.top.content=data
'm.top.content=content                                                              <<<<<<<<<<<<<<<<<<THIS DOES NOT WORK

In the post I was referencing that setting m.top.content=content doe not work so setting m.top.content=data as shown above does. As for the chat room, I didn’t know this existed, thanks for pointing this out. Thanks again.