Expand my Community achievements bar.

Learn about Edge Delivery Services in upcoming GEM session
SOLVED

Getting Error wheyn trying to use SharedCollection

Avatar

Level 2

Hello all, I am really new to AFCS and I have a question for ya'all.

I get this error when trying to pass data to a SharedCollection:

Error: Each item in a sharedCollection requires a unique ID. Please have your items

either implement mx.core.IUID, or specify 'sharedCollection.idField' so that the

collection knows which field of your item is unique.

I am not sure what the problem is, how di I add an id field?? Here is my test code

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:rtc="AfcsNameSpace">
     <mx:Script>
          <![CDATA[
               import mx.events.CollectionEvent;
               import com.adobe.rtc.events.SessionEvent;
               import com.adobe.rtc.events.SharedPropertyEvent;
               import com.adobe.rtc.sharedModel.SharedProperty;
               import com.adobe.rtc.sharedModel.SharedCollection;
               
               private var sc:SharedCollection;
               
               private function init():void
               {
                    sc = new SharedCollection();
                    sc.sharedID = '_testOne';
                    
                    sc.connectSession = this.connectSession;
                    sc.addEventListener(CollectionEvent.COLLECTION_CHANGE, this.rtnSession);
                    sc.subscribe();
               }

               private function rtnSession(evt:SharedPropertyEvent):void
               {
                    
               }
               private function onSessionSync(event:SessionEvent):void{
                    if(connectSession.isSynchronized){
                         this.init();
                    }
               }
               private function SendData():void
               {
                    var obj:Object = new Object();
                    obj.fname = 'tim';
                    obj.lname = 'gallagher';
                    
                    this.sc.addItem(obj);
               }
               
          ]]>
     </mx:Script>

     <rtc:LocalAuthenticator id="auth" userName="AnyArbitraryUsername"  />
     <rtc:ConnectSessionContainer id="connectSession" authenticator="{auth}" synchronizationChange="onSessionSync(event)" />
     <mx:Button label="Press ME" click="SendData();"/>
</mx:Application>

Can anyone tell me what I am doing wrong??

Thanks for the help,

timgerr

1 Accepted Solution

Avatar

Correct answer by
Former Community Member

Close - idField needs to be a string, so try this :

// only needs to be called once, after you create sc - note it's a String

sc.idField = "tmpID";

private function SendData():void

{

var obj:Object = new Object();

obj.fname = 'MeName';

obj.lname = 'MeLastName';

obj.tmpID = UIDUtil.createUID();

this.sc.addItem(obj);

}

hope that helps

nigel

View solution in original post

10 Replies

Avatar

Employee

Hi Timgerr,

You need to set the idField of the SharedCollection. In your case sc.idField = "fname" . So specify a field within the item to use as a unique ID. If you explore the collectionNode _testNode you would notice that all your items are stored as individual nodes named after the objects idField.

So any object you insert into SharedCollection, just ensure that it has the fname field.

Thanks

Avatar

Former Community Member

Arun is right (as usual) about how to assign the idField of your ShareCollection - but it's likely that "fname" isn't going to have a unique value in each of your items. Basically, the idea is that items in a SharedCollection need to have a field in them whose value is unique among all items. You can generate your own unique IDs from the client (the mx toolkit has a UIDUtils class), or the primary keys of a database row would also work.

nigel

Avatar

Level 2

OK so I did this

private function SendData():void
{
     var obj:Object = new Object();

     obj.fname = 'MeName';

     obj.lname = 'MeLastName';
     var tmpID:String = UIDUtil.createUID();
     sc.idField = tmpID;
     this.sc.addItem({tmpID:"obj"});

}

And I am getting the same error.  I am using the local (AIR) server app.

Am I doing it right?

Thanks for the help.

timgerr

Avatar

Correct answer by
Former Community Member

Close - idField needs to be a string, so try this :

// only needs to be called once, after you create sc - note it's a String

sc.idField = "tmpID";

private function SendData():void

{

var obj:Object = new Object();

obj.fname = 'MeName';

obj.lname = 'MeLastName';

obj.tmpID = UIDUtil.createUID();

this.sc.addItem(obj);

}

hope that helps

nigel

Avatar

Level 2

Thanks for the help, like I said, I am learning this.  I have another question for ya if that is ok.  When I run this program, I added a listener to the return to see howmany items are in the sharedcollection.  I keep getting 1 item, does the Sharedcollection act like an ArrayCollection?  How can I add many objects and share them to others, is SharedCollection the best way to do it?

Thanks,

timgerr

Here is my code again:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:rtc="AfcsNameSpace">
     <mx:Script>
          <![CDATA[
               import mx.events.CollectionEvent;
               import com.adobe.rtc.events.SessionEvent;
               import com.adobe.rtc.events.SharedPropertyEvent;
               import com.adobe.rtc.sharedModel.SharedProperty;
               import com.adobe.rtc.sharedModel.SharedCollection;
               import mx.utils.UIDUtil;
               
               private var sc:SharedCollection;
               
               private function init():void
               {
                    sc = new SharedCollection();
                    sc.sharedID = '_testOne';
                    sc.idField = "tmpID";
                    sc.connectSession = this.connectSession;
                    sc.addEventListener(CollectionEvent.COLLECTION_CHANGE, this.rtnSession);
                    sc.subscribe();
                    
               }

               private function rtnSession(rtn:CollectionEvent):void
               {
                    trace(rtn.items.length.toString());     
               }
               private function onSessionSync(event:SessionEvent):void{
                    if(connectSession.isSynchronized){
                         this.init();
                    }
               }
               private function SendData():void
               {
                    var obj:Object = new Object();
                    obj.fname = 'Don';
                    obj.lname = 'Knots';
                    obj.tmpID = UIDUtil.createUID();
                    this.sc.addItem(obj);
               }
               
          ]]>
     </mx:Script>

     <rtc:LocalAuthenticator id="auth" userName="AnyArbitraryUsername"  />
     <rtc:ConnectSessionContainer id="connectSession" authenticator="{auth}" synchronizationChange="onSessionSync(event)" />
     <mx:Button label="Press ME" click="SendData();"/>
</mx:Application>

Avatar

Employee

Yes SharedCollection acts like an ArrayCollection (SharedCollection extends mx.collections.ListCollectionView).SharedCollection is a cool way to share many objects, but unfortunately you may have to call addItem method multiple times and insert objects into the collection one at a time. (in other words you cant do block insert)

Avatar

Level 2

So one cannot add objects or arrays to a sharedcollection?

Thanks for the help, I am learning a lot.

timgerr

Avatar

Employee

Technically you can, as SharedCollection behaves like an Collection. The items inside a collection can them selves be of complex data types. So you can store ArrayCollection and Objects in an item of the sharedCollection.

var obj:Object = new Object();
var myAC:ArrayCollection = new ArrayCollection();
myAC.addItem( { name: "Lee", country: "China", language: "Mandarin" } );
myAC.addItem( { name: "Jodie", country: "UK", language: "English" } );
obj.item = myAC;
obj.tmpID = UIDUtil.createUID();
this.sc.addItem(obj);

Avatar

Level 2

Thanks for the help and code, that helps a lot.

timgerr

Avatar

Level 3

I am trying to wrap an XMLListCollection. Is this possible?

I basically used:

sc = new SharedCollection(x_GridData); (Where x_GridData is an XMLListCollection.)

The problem is that each item dosen't have a unique id field. Is there a way to add a UID field to an XMLListCollection OR is there a specific way to wrap XMLListCollection's so they can be shared?

My next approach (if there is no alternative) is to share an object that contains changed items and then update the XMLListCollection locally.

The following has evaluated to null or missing: ==> liqladmin("SELECT id, value FROM metrics WHERE id = 'net_accepted_solutions' and user.id = '${acceptedAnswer.author.id}'").data.items [in template "analytics-container" at line 83, column 41] ---- Tip: It's the step after the last dot that caused this error, not those before it. ---- Tip: If the failing expression is known to be legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)?? ---- ---- FTL stack trace ("~" means nesting-related): - Failed at: #assign answerAuthorNetSolutions = li... [in template "analytics-container" at line 83, column 5] ----