9 Replies Latest reply on Mar 20, 2007 1:51 PM by phi2265

    AS Question..

    phi2265 Level 1
      So I have a database to keep track of stats. Every time the application loads, I do a couple of checks on a timer to make sure the connection is active, then I call postHit('uniq') or postHit('repeat') and it adds +1 to either uniqueVisit or repeatVisit depending on which it is. This works fine. The problem, however, is when I try to call the function postHit('photo') from another mxml component.. I get an error in flash player.

      TypeError: Error #1009 Cannot access a property or method of a null object reference.
      at galSel2/postHit()

      galSel2 is the name of my mxml component. postHit() is the function I'm calling. Here's my code for the functions:

      this is stats.as
      in my main application, along with galSel2 I have
      <mx:Script source="stats.as"/> so I can use the functions in different components.

      import valueObjects.suvozVisits;
      import flash.net.SharedObject;
      import mx.data.DataService;
      import mx.collections.ArrayCollection;
      import flash.utils.Timer;
      import flash.events.TimerEvent;

      public var visits:SharedObject = SharedObject.getLocal("visits");
      public var visit:suvozVisits;
      public var visitds:DataService;
      public var visitAdded:Boolean = new Boolean(false);
      [Bindable]
      public var visitArray:ArrayCollection;
      public var hitTimerInt:uint = 60000;
      public var hitTimer:Timer = new Timer(hitTimerInt);
      public var timerCounter:int = 0;

      public function initVisit(endUser:String):void{
      visitds = new DataService("visits");
      visit = new suvozVisits;
      visitArray = new ArrayCollection();
      visitds.fill(visitArray);
      if (endUser == 'client'){
      hitTimer.addEventListener(TimerEvent.TIMER, hitTimerHandler);
      hitTimer.start();
      }
      }

      public function hitTimerHandler(event:TimerEvent):void{
      checkVisited();
      timerCounter++;
      if (timerCounter == 3){
      hitTimer.stop();
      }
      }

      public function postHit(type:String):void{

      visit = visitArray[0];
      if (type == 'repeat'){
      visit.repVisits++;
      }else if (type == 'unique'){
      visit.uniqVisits++;
      }else if (type == 'news'){
      visit.newsHits++;
      }else if (type == 'photo'){
      visit.photoHits++;
      }else if (type == 'video'){
      visit.videoHits++;
      }else if (type == 'spot'){
      visit.spotHits++;
      }else if (type == 'biz'){
      visit.bizHits++;
      }
      visitds.createItem(visit);
      }

      public function checkVisited():void{
      if (visitAdded == false){
      if (visits.data.firstVisit == null){
      visits.data.firstVisit = new Boolean(true);
      }
      if (visits.data.firstVisit == false){
      postHit('repeat');
      visitAdded = true;
      }
      if (visits.data.firstVisit == true){
      postHit('unique');
      visits.data.firstVisit = false;
      visitAdded = true;
      }
      }


      In the main application InitVisit('client'); is called on application load to add the statistic. I don't understand why what I'm trying to do isn't working. I understand the "null" error, it means that my variables aren't declared.. but I can't seem to figure this out...


      All help/hints/suggestions greatly appreciated! Thanks...


        • 1. Re: AS Question..
          phi2265 Level 1
          The other error I get when calling the function postHit(); is:
          RPC Fault faultString="Item with id '1' already exists. Error on destination 'visits' " faultCode="Local.Call.Failed" faultDetail="null"

          I think it has something to do with how i'm updating the database. I'm using visitds.createItem(visit); And I think that its telling me I already have an item in the database with an id of 1, which is the only entry in the database and it needs to stay that way. I need another way to update the database....


          • 2. Re: AS Question..
            dimival Level 1
            Can i see your item's class?? And also can you post what properties are you setting for the new item you want to add?

            That might give me an idea what you are exactly doing.
            • 3. Re: AS Question..
              phi2265 Level 1
              here's the item's class:
              package valueObjects
              {
              [Managed]
              [RemoteClass(alias="suvozVisits")]

              public class suvozVisits
              {

              public var ID:Number = 0;
              public var uniqVisits:Number = 0;
              public var repVisits:Number = 0;
              public var newsHits:Number = 0;
              public var photoHits:Number = 0;
              public var videoHits:Number = 0;
              public var spotHits:Number = 0;
              public var bizHits:Number = 0;


              public function suvozVisits()
              {
              }

              }
              }

              when the page loads, it adds to either uniqVisits, or repVisits. And at other times I'm trying to add to newsHits or photoHits... I keep getting an error saying item with ID 1 already exists.. but it works fine when posting repVisits or uniqVisits.
              • 4. Re: AS Question..
                dimival Level 1
                What about this:

                visit = visitArray[0];
                if (type == 'repeat'){
                visit.repVisits++;
                }else if (type == 'unique'){
                visit.uniqVisits++;
                }else if (type == 'news'){
                visit.newsHits++;
                }else if (type == 'photo'){
                visit.photoHits++;
                }else if (type == 'video'){
                visit.videoHits++;
                }else if (type == 'spot'){
                visit.spotHits++;
                }else if (type == 'biz'){
                visit.bizHits++;
                }
                visitds.createItem(visit);
                }

                In this code you assing a value from an array to your visit object (visit = visitArray[0];), then you modify it's properties and try to create a new one, but you never change it's ID, so when you did visit = visitArray[0]; your visit object has the ID of the object in the array (ID = 1 according to the error). That's why it says there's already an object with ID=1, because you are trying to create a new item using an existing id.
                • 5. Re: AS Question..
                  phi2265 Level 1
                  Yeah I figured that out last night before leaving the office.. The thing is, I don't want to make a new item, but update the exsisting item. I mean I could delete the current record and then make a new one.. but I don't really want to do that. Is there a way to update? I tried messing with a few things.. but no luck.


                  • 6. Re: AS Question..
                    dimival Level 1
                    Of course you can update, you just need to call commit().

                    If your DataService autocommit property is true, then whenever you modify anything of a managed item, an update will be triggered.
                    If the autocommit property is set to false, then after modifying an item you need to call the DataService.commit() method.

                    It is very important that your Assembler has a method for updating, this method will be triggered when you commit() is called.

                    • 7. AS Question..
                      phi2265 Level 1
                      How to I set an item to be managed?
                      My class, if you scroll up a little, says that its managed.. but I don't know anything about this part of DataServices and I haven't been able to find anything in the docs that I understand. Do you have any sample code you can paste in or link me to?

                      EDIT:
                      Or does it work like this? (I'm not at the office so I cant try it out..)
                      visit.photoHits++;
                      visitds.commit();

                      Are all instances of the managed class managed by the DataService? I guess I don't see where the link between the DataService and the Object is.


                      • 8. Re: AS Question..
                        dimival Level 1
                        When you make a call to the fill( ) method of a DataService you obtain a Managed Collection of items, then every item on the collection is Managed so if you change a value of an item and then do a call to commit( ) it will trigger an update.

                        DataServices components have methods for creating and deleting, the update simply by commiting it will be triggered. Remember that is very important that in your assembler class (the destination the dataservice is pointing at, the backend) has a method for creating, updating and deleting, otherwise calling a commit(), createItem(), deleteItem() on the DataService will have no effect at all.

                        I recommend you to read chapters 46 and 46 of the Developers Guide document
                        • 9. Re: AS Question..
                          phi2265 Level 1
                          I figured out why I was having so much trouble.. the CFCs that I had were not up to date. They were missing the some of the values for the class variable. Works now!

                          Thanks for the help.