3

I Made a factory that keeps the information in my scopes in a series of 6 pages. Now when the user completes the 6th page and pushes the object I want the factory to reset to empty arrays again.

I already tried a lot with the timeout and apply elements, also tried a lot of combinations to set the array to empty (null, "", {}). but it still loads the old information when I load the page again(page 1/6).

The submit function (That also needs to reset the scopes) is

$scope.send = function(){
    if(ArrayInfo.Checkmark == true){
        firebase.database().ref('lorem/' + ArrayInfo.Ordernumber).set({
          info: ArrayInfo,
          Dates: Dates,
          gasmeter: gasmeter,
          gasmeter1: gasmeter1  
        }).then(function(){
          firebase.database().ref('lorem2/' + ArrayInfo.currentYear).set({
            last_number: ArrayInfo.Ordervalue
          });
        }).then(function(){
          //ArrayInfo = {};
          setTimeout(function(){
            ArrayInfo = "";
            $scope.info = "";
            $scope.$apply();
            $scope.$digest();
          }, 50);

        });
      //close newrental
        setTimeout(function(){
          if (window.confirm('Information saved! You are ready to leave this screen? no changes possible after this point'))
          { 
            //disable back button in home 
            $ionicHistory.nextViewOptions({
              disableBack: true
            });
            //go home
            $state.go("app.auth");
          }
          //error close newrental
          else
          {
             alert("Take your time");
          }
        }, 50);

    }
    //error send array
    else {
      alert("Please accept the terms and conditions.");
    }
  }

My factory looks like this

mainapp.factory("infoFactory", function(){
  ArrayInfo = {};
  placeholders = {
    "licenseone" : "img/placeholder.png",
    "licensetwo" : "img/placeholder.png",
    "licensethree" : "img/placeholder.png",
    "licensefour" : "img/placeholder.png",
    "imageone" : "img/front.png",
    "imagetwo" : "img/sideleft.png",
    "imagethree" : "img/back.png",
    "imagefour" : "img/sideright.png",
    "imagefive" : "img/roof.png",
    "imagesix" : "img/placeholder.png",
    "imageseven" : "img/placeholder.png",
    "imageeight" : "img/placeholder.png"
  };
  gasmeter = {
    "url" : "img/gas/gas1.png",
    "gasvalue" : "1"
  }
  gasmeter1 = {
    "url" : "img/gas/gas1.png",
    "gasvalue" : "1"
  }
  ArrayInfo.returned = false;
  RawDate = {};
  Dates = {};

  console.log(ArrayInfo);

  return ArrayInfo;
  return gasmeter;
  return gasmeter1;
  return placeholders;
  return RawDate;
  return Dates;
})

and I load the information in my controller like this

$scope.info = infoFactory;
$scope.Dates = Dates;
$scope.RawDate = RawDate;
$scope.gasmeter = gasmeter;
$scope.gasmeter1 = gasmeter1;

The angular version I am using is "3.6.6"

4
  • there is no "angular 3.6.6"; Angularjs is at 1.6.4 and Angular is at 4.1.0; the 3.x branch was skipped entirely. Commented Apr 29, 2017 at 15:55
  • My bad, i confused my angularfire with my angular version. Its updated now. Commented Apr 29, 2017 at 16:10
  • I have multiple arrays so i figure i need multiple returns? Or do i need to call them by infoFactory.Dates by example? Commented Apr 29, 2017 at 16:14
  • @AlonEitan well that works! is there any way to easy reset it when setup like this? Commented Apr 29, 2017 at 16:24

1 Answer 1

1

First of all, when you put return in your code, there's no use to include additional code after that, because it will never run. You need to return an Object instead.

mainapp.factory("infoFactory", function(){
  ArrayInfo = {};
  placeholders = {
    "licenseone" : "img/placeholder.png",
     // Rest of the images
  };
  gasmeter = {
    "url" : "img/gas/gas1.png",
    "gasvalue" : "1"
  }
  gasmeter1 = {
    "url" : "img/gas/gas1.png",
    "gasvalue" : "1"
  }
  ArrayInfo.returned = false;
  RawDate = {};
  Dates = {};

  console.log(ArrayInfo);

  return { 
    ArrayInfo: ArrayInfo, 
    gasmeter: gasmeter, 
    gasmeter1: gasmeter1, 
    placeholders: placeholders, 
    RawDate: RawDate, 
    Dates: Dates 
  };
})

Now you can inject infoFactory to the controller and use it like this: infoFactory.RawDate.

Now, if you want to reset the factory, you can add a function that reset all the data:

mainapp.factory("infoFactory", function(){
  // Save a reference to the current pointer of the factory, so you won't loose it inside other scopes  
  var self = this;

  self.params = {
       ArrayInfo: {},
       placeholders: {},
       gasmeter: {},
       gasmeter1: {},
       ArrayInfo: false,
       RawDate: {},
       Dates: {}
  };

  self.reset = function() {
     self.params.ArrayInfo = {};

     self.params.placeholders.licenseone = "img/placeholder.png";

     self.params.gasmeter.url = "img/gas/gas1.png";
     self.params.gasmeter.gasvalue = "1";

     self.params.gasmeter1.url = "img/gas/gas1.png";
     self.params.gasmeter1.gasvalue = "1";

     self.params.ArrayInfo.returned = false;

     self.params.RawDate = {};

     self.params.Dates = {};
  }
  self.reset(); // Call this function by default in order to initially set the factory properties 

  return { 
    reset: self.reset, // You can export the reset function and use it outside the factory too
    ArrayInfo: self.params.ArrayInfo, 
    gasmeter: self.params.gasmeter, 
    gasmeter1: self.params.gasmeter1, 
    placeholders: self.params.placeholders, 
    RawDate: self.params.RawDate, 
    Dates: self.params.Dates 
  };
})

Now when you have a reset function, you can use it like this outside the factory: infoFactory.reset() whenever you want to reset the data to the initial state. I created inside the factory a base object (this.params = { .. }) and saved inside it all the details properties, inside the reset function I have updated those properties without breaking the original references (Working example).

The above is just an example, but you can (or perhaps should) encapsulate the params of the factory, and only allow the user to control and change the values via helper functions. Example of how to do it:

mainapp.factory("infoFactory", function(){
  var self = this;

  self.params = {
     returned: false,
  };

  return {
     setReturned: function(val) { self.params.returned = val === true; },
     returned: function() { return self.params.returned; }
  }
});

The above example will hide the actual params.returned from the user outside the factory, and only allow it to set the returned flag via helper function, i.e infoFactory.setReturned( true ); or infoFactory.setReturned( false );, and inside that setReturned function you can implement complex logic to validate the value sent to the function. Note that infoFactory.setReturned( 'invalid value!!!' ); will set the returned flag to false since i'm validating the value using the strict === operator - val === true.

Then, to get the value from the factory you call the infoFactory.returned() function - By using a function you're blocking outside access to the properties of the factory.


As a side note - Don't use setTimeout(function(){ ... }); Use $timeout and $interval and then you won't need $scope.$apply(); + $scope.$digest(); in order to manually run a digest cycle because it is being handeled nativaly by Angularjs for you

Sign up to request clarification or add additional context in comments.

13 Comments

The first version of the Factory helps me alot, im kinda confused about the second Factory tho. It looks awesome piece of code but does'nt seem to work for me. My arrayinfo doesn't get defined properly using it. I'm using the same piece of code as with the first factory '$scope.info = infoFactory.ArrayInfo;'
I literally plugged the complete Factory in place of the old one. My controllers sees self. as undefined and the self.reset() is undefined ... Probally doing something wrong :)
Okay cool, My factory is exactly the code of the second snippet right now. Nothing more nothing less.
for now using code like vm.infoFactory.ArrayInfo = {}; wil do the trick in the send function. For some reason that does work now. Thank you alot for the help, really helped!
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.