Skip to content
This repository has been archived by the owner on Jul 1, 2020. It is now read-only.

route with forms in ng-view getting error "Cannot set property '$validationSummary' of undefined" #58

Closed
rluiten opened this issue Aug 14, 2015 · 9 comments
Labels

Comments

@rluiten
Copy link

rluiten commented Aug 14, 2015

I have a hiccup at work, and have been trying to reproduce it.
Interaction of routes with validation, I think it might be tied up with $destroy of scopes, but not sure.

This example is not the same behaviour I have at work but this is related.
It is similar as it is the same error message 1. below.
There is a chance I have just mucked my code and so its my bug not one in angular-validation, but I think I have squashed most of the dumb out of the example now.

http://plnkr.co/edit/c94r1xA8e0M3iXnWCe6w?p=preview

Load the demo, then click in FIeld1 and click out no error.
Load the demo, then click in Field1 and type a letter no error.
Now click on "First" next to "Choose Route" this activates the route.

Now two errors occur.

  1. Go to field 1 and type a letter get an error in javascript console.
    "TypeError: Cannot set property '$validationSummary' of undefined"
  2. The following error appears if you click in Field1 and the click out of it to blur.
    "Uncaught TypeError: Cannot read property 'isValidationCancelled' of null"

Sometimes I can get error case 1. without typing anything into field one, but its hit and miss and not frequently.

If line 37 is commented out - "var v = new validationService()", then error 1 does not happen, but 2. still does.

Cheers, Rob.

@ghiscoding
Copy link
Owner

Hello Rob,

I can't reproduce any of your errors 1 or 2, but in order for me to fix these undefined or null problems, I'll have to know exactly which lines it gives the error (from the unminified versions). What I suggest you is to load the unminified versions and pass me the line number and the variable name giving the error...

Does it give you any other functionality issues, or is it simply the fact that it throws errors in the console? If it's just JS console errors, then it's easy to fix, I would simply check if variable is not null before querying it or whatever else is needed.

Let me know

@rluiten
Copy link
Author

rluiten commented Aug 14, 2015

It is not just console errors.
I may have removed to much from what I had earlier, that showed other stuff was not working.
I hope you can see the console errors at least.

I've put back back in the validation summary display stuff of the outer controller and field.
Have also switched over to non minified validation libraries.

I've added second route, and defaulted to First route, now a console error occurs immediately on page load [not surprising to me]. Note that if you add a char to Field1 error goes away, but the template field value of Field1 jsut above is not displayed between the [[]] markers, removing a character only restores the red box when you leave the field it does not restore the error message below Field1, And the error on clearing FIeld1 only gets applied when leaving Field1 not after timeout. So something is not running any more I think.

The case at work is stopping the route view from changing properly between views, and it is occurring when we switch between routes without any other inputs, so that both the before and after views are visible in the view. I have not been able to get that to happen in this example so far.
This is not the same error, I remember a $destroy handler in one of the stack tracers at work for the $validationSummary null message. I'll be revisisting works error monday morning again.

Oops updated the demo a bit.
http://plnkr.co/edit/c94r1xA8e0M3iXnWCe6w?p=preview
[Oh it is still the same link]

Rob.

@ghiscoding
Copy link
Owner

Ok so here is what I found so far, you are using 3 different VMs and you expect them to be completely independent but it doesn't look like they are. I just added a couple of console.log here and there, mostly just before the error and I can see that the first formName of the element it found is test because the first one showing in the console is the index.html and the element is f1 but if we add another console log, the VM that is showing is not the first one, it's instead the one that holds the form firstForm and so they are not in sync. I think that what is happening is that the validationService might not be 3 independent services, I'll have to confirm that but so far that is what I found. Which is also the reason that if you comment out your other 2 VMs it will work, so it looks like they are overwriting each others.

Hmmm ok I think I found the problem, this problem will most probably only show up when using the controllerAs syntax, I have too many global variables in the validation-common.js file, I should use the this to make these variables really owned by each independent object. OOP inside javascript is still risky business. So the fact that they are global makes them exist outside of each VM object, so everytime you touch the Global Options (in your case you declare the controllerAs) it will overwrite previous call and is mixing up the VMs. It looks like I'll have a lot of refactoring to do and lot of potential to break, so it will probably take a few days to fix.

@rluiten
Copy link
Author

rluiten commented Aug 15, 2015

LOL. I just came back to this page to re read what i wrote to see if i had missed something, and saw your reply appear...

Anyway ouch that sounds like it might be a chunk of work to clean up.

@ghiscoding
Copy link
Owner

Yeah OOP in javascript is still a little bit of a pain and it looks like I didn't fully understand it, I'll have to review all my code. Considering that we'll eventually have to use TypeScript for Angular 2.0, that would have probably helped in my situation :S

@rluiten
Copy link
Author

rluiten commented Aug 15, 2015

Angular 2 is very different beast, i suspect its a re-engineer from ground up no path of migration except for concepts. I hope to use React some time soon, I've been tinkering with it, and so much stuff is just simpler.

@ghiscoding
Copy link
Owner

I changed a lot of code to make the validationService more independent but now it's seems that it's too much independent and now the Directive does not have access to the same Global Options anymore, because well it's not the same object and it's no more Global anymore... so I'm seriously thinking about rolling back.

Now the only 2 options that I see that would work, but are really not interesting:

  1. pass the ControllerAs into the DOM input element as a new attribute
  2. use only the validationService for validation. To me, none of these 2 choices are really interesting.

Actually thinking about it while writing, there might be another option, I could rollback everything and make it the way it was and possibly add a new Global Options being controller and if it's pass, it would then make independent controllerAs which would not collide with each others. That way, everything stays global and these global properties can still be accessed by both the Directive and Service. The code would look like this var v2 = new validationService({ controller: 'FirstCtrl', controllerAs: vm2 });

@ghiscoding
Copy link
Owner

It's fixed now, I ended up staying with variables that are shared with Directive & Service (hence the word Global Options), going fully independent wasn't going well and was removing too many functionalities and would change user code, better not to do that. I hate to break code.

But you have to know that your code was actually divided in 2 problems which I fixed:
1- Multiple ControllerAs wasn't working correctly because the $validationSummary is saved into each forms inside each ControllerAs, but since you had many it was bring overwritten by the last one.
2- You use Route inside your project and you expected it to not affect the top form (the one outisde of your Route).

For the problem 2), I added a new Global Options that you need to use to fix this issue. The new option is resetGlobalOptionsOnRouteChange (with this name, you should understand the meaning of it) and you need to put it to False (by default it's set to True) on your top Controller.
So in code, you need to have your first Controller, the one outside of the Route like the following:

var vm = this;
var v1 = new validationService({ controllerAs: vm, resetGlobalOptionsOnRouteChange: false });

You can see the Global Options for this new option of resetGlobalOptionsOnRouteChange

Looks like you'll need to pay a beer, after so many code change for you, next time I visit Australia again :P

@rluiten
Copy link
Author

rluiten commented Aug 23, 2015

Had a bit of a play, looks decent, I can't use it in our problem area at the moment as we are in count down to a release, and can't afford to reset some of the testing progress.

Cheers Rob.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants