## Moodle for mobile

Hi All,

I'm working on enabling one of my activity modules for MoodleMobile. I've got the development environment set up and working with MoodleMobile running in Chromium, this successfully connects to my Moodle test systems. This wasn't too painful since I've already written a few Android apps from scratch, one of which was done with Cordova.

I've got a basic module set up and have put in the appropriate zip file and db/mobile.php entry. When I start up MoodleMobile, I can see from my webserver log that the zip file is downloaded, so clearly the set up to tell MoodleMobile that the remote addon is available is working and I get Registered addon messages for course content, prefetch and link handler in the browser console.

However, that's the extent of what I can get to work. The icon which I defined in the handler getController method isn't used (I still see the jigsaw piece icon for an unsupported module) and when I click on the activity I get the "You can still use it using your devices browser" message, although the earlier part about the mod not being supported and contacting your sysadmin is now missing, which suggests that the module is being partially detected at this point causing that message to be hidden. There is not nothing else which relates to the module, so I can only assume that something critical is missing, but I'm at a loss as to what that could be since I've largely copied the page module code verbatim (with appropriate adjustments to the mod name.

So the question is, how do validate the basic structure of the plugin so I can work out what is wrong, or trigger an error message that gives me a clue,

Thanks in anticipation!

Average of ratings: -

Hi Tim,

good job getting this far! Let's see if we can fix this problem.

The service responsible of handling the activities is $mmCourseDelegate, so that's one of the places to look. I'd add some more console.log in$mmCourseDelegate#updateContentHandlers and $mmCourseDelegate#updateContentHandler to make sure your activity is enabled (added to enabledHandlers). If the activity is not added to enabledHandlers then it probably means that the isEnabled function in your activity is returning false, you should check why is that. Maybe some missing WebService? If the activity is added to enabledHandlers, then check that the function$mmCourseDelegate#getContentHandlerControllerFor is able to retrieve the handler (maybe the name is not the same?).

If you want to have access to enabledHandlers from the browser console you can just do something like this in the service:

window.enabledHandlers = enabledHandlers;

That way you'll have a global variable that can be accessed via the console.

I hope this helps you!

Dani

Average of ratings: -
Hi Dani,

Thanks for your help. I've added in a load of extra logging as you suggested to $mmCourseDelegate. With the extra debugging, I can see that all of the internal mods are processed by the updateContentHandler method prior to the point where my module is registered. Looking at the log output I see the following immediately after the 3 Registered log entries for my addon:$mmEvents: Event remote_addons_loaded triggered.
$mmCoursePrefetchDelegate: Updating prefetch handlers for current site. Since my addon contains a content handler, I would also have expected the "Updating content handlers for current site." log entry to be sent, followed by a repeat of the earlier log entires for all the handlers, but with my addon included. However, that doesn't happen. I tried disabling the prefetch handler in my addon config and this caused the content handler registration to be re-run (a minor triumph). So the immediate problem is that my prefetch handler is causing a problem, which might be because I've not written the webservice yet. I'm going to leave the prefetch code for now, since I wasn't going to look at this as the first task. However, my addon still fails to activate and the updateContentHandler method never calls the isEnabled method on my addon. As far as I can tell, it fails on this line: handlerInfo.instance =$mmUtil.resolveObject(handlerInfo.handler, true);

The console.log prior to this line is displayed, but the one immediately after it is never printed. Digging into the $mmUtil.resolveObject method, I added some more logging output. The method gets to this line and silently fails, with none of the following logging output being generated: resolved =$injector.get(toInject[0]);

I tried sticking a try-catch around this to see if there was an exception that was being suppressed somewhere higher up, but got nothing. I haven't as yet been able to identify where \$injector comes from, so that's as far as I can get trying to debug this. Any advice gratefully received!

Average of ratings: -

Hi Tim,

that's weird. Can you send me the main.js and the handlers.js files in your plugin? You can send them to mobile@moodle.com. I'll check if I see why is it failing.

Cheers,

Dani

Average of ratings: -
Actually I think I've found the initial problem, I was using the manual packaging procedure described here:

and I hadn't fully appreciated the step which said "place all the JavaScript code of your addon in a single file named addon.js. This file needs to be in your addon's root folder." I didn't realise that it meant to duplicate absolutely everything, I thought it just related to the content of main.js, so I was making addon.js as a copy of main.js.

Which begs the question as to why this duplication step is necessary, it seems like a redundant thing to do, when all the original js files are included in the final zip as well but seemingly not used. Is this forced upon you by the angular.js framework, or was it a deliberate decision for reasons I have yet to understand?

The module now seems to be starting up. I've still got some issues, which might be the subject of a further post, but I'm also getting meaningful error messages from the console so I'm going to work through them first.

Thanks again, hopefully I'll now have something working soon!

Average of ratings: -

Hi Tim,

I'm glad you found the problem!

Placing all the code in a single file was a deliberate decision we made. It has 2 reasons:

1. The app only needs to execute 1 file that has a fixed name, there's no need to iterate over all the files in the ZIP file and execute them.
2. We can control the order of the file content, so the module declaration (main.js) is at the start of the file. Otherwise we'd have to look for the main.js (it could have a different name!) and load it first.