Appcelerator [ERROR] : Failed to parse ...controllers/picture-list.js.js - appcelerator

When trying to run a project on a Android-phone, Appcelerator gives an error:
[INFO] : Alloy compiled in 6.57967s
[INFO] : Alloy compiler completed successfully
[INFO] : JavaScript files need to be encrypted
[INFO] : Processing JavaScript files
[ERROR] : Failed to parse /Users/bas/Documents/Appcelerator_Studio_Workspace/Whatever-App-master/Resources/android/alloy/controllers/picture-list.js.js
[ERROR] : Invalid left-hand side in assignment expression (21:4)
The stupid thing is that Appcelerator made the file itself:
[INFO] : [picture-list.js.xml] view processing...
[INFO] : style: "picture-list.js.tss"
[INFO] : view: "picture-list.js.xml"
[INFO] : created: "Resources/android/alloy/controllers/picture-list.js.js"
[INFO] : created: "Resources/android/alloy/styles/picture-list.js.js"
... so why make a file and than later on complain about it?
The app is not running now, stops after compiling.
picture-list.js:
function __processArg(obj, key) {
var arg = null;
if (obj) {
arg = obj[key] || null;
delete obj[key];
}
return arg;
}
function Controller() {
require("/alloy/controllers/BaseController").apply(this, Array.prototype.slice.call(arguments));
this.__controllerPath = "complaints/picture-list";
this.args = arguments[0] || {};
if (arguments[0]) {
__processArg(arguments[0], "__parentSymbol");
__processArg(arguments[0], "$model");
__processArg(arguments[0], "__itemTemplate");
}
var $ = this;
var exports = {};
$.__views.pictures = Ti.UI.createTableViewSection({ // line 21
id: "pictures"
});
$.__views.pictures && $.addTopLevelView($.__views.pictures);
exports.destroy = function() {};
_.extend($, $.__views);
_.extend($, exports);
}
var Alloy = require("/alloy"), Backbone = Alloy.Backbone, _ = Alloy._;
module.exports = Controller;
picture-list.js.js:
function __processArg(obj, key) {
var arg = null;
if (obj) {
arg = obj[key] || null;
delete obj[key];
}
return arg;
}
function Controller() {
require("/alloy/controllers/BaseController").apply(this, Array.prototype.slice.call(arguments));
this.__controllerPath = "picture-list.js";
this.args = arguments[0] || {};
if (arguments[0]) {
__processArg(arguments[0], "__parentSymbol");
__processArg(arguments[0], "$model");
__processArg(arguments[0], "__itemTemplate");
}
var $ = this;
var exports = {};
$.__views.picture - list.js = Ti.UI.createView({ // line 21
id: "picture-list.js"
});
$.__views.picture - list.js && $.addTopLevelView($.__views.picture - list.js);
exports.destroy = function() {};
_.extend($, $.__views);
_.extend($, exports);
}
var Alloy = require("/alloy"), Backbone = Alloy.Backbone, _ = Alloy._;
module.exports = Controller;

Before writing absurd things about a platform which is used by millions of developers, it is always better to know the truth by providing the necessary info.
Titanium has to create JS files first, then it process them for any logical errors.
The info you have provided here is just 50% & your answer cannot be resolved until you share the code of this file picture-list.js.js from your app project, not in Resources. If not possible to share whole code, then it should be fine to share first 40-50 lines of code.
Secondly, I can see duplicated js.js in your files XML, JS, TSS which should not be there.
Lastly, you can just go to this file /Users/bas/Documents/Appcelerator_Studio_Workspace/Whatever-App-master/Resources/android/alloy/controllers/picture-list.js.js & share the line no. 21 here which I guess contains some sort of assignment which is invalid due to some subtle mistakes of yours.

Because the compiler lints the JavaScript files, it also validates it.
So what you're seeing is a JavaScript error in the picture-list.js file, I assume line 21.
You can find more information about the error: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Invalid_assignment_left-hand_side
Edit: Based on your code.
You can see this, (it is invalid JS)
$.__views.picture - list.js = Ti.UI.createView({ // line 21
id: "picture-list.js"
});
This is probably caused by a - in your original code, or has to do with the name of the controller. - is not supported in names and Id's. I recommend changing it with an underscore, so picture_list.js.
Dashes (-) in javascript are not supported in variables names, thats why this is going wrong!

Related

Ckeditor5 error with undoing multiline paste operation

I have a plugin for my ckeditor build which should convert pasted content with formulas,
separated by '(' ')', '$$' etc. into math-formulas from ckeditor5-math (https://github.com/isaul32/ckeditor5-math). I changed the AutoMath Plugin so that it supports text with the separators.
I have run into a problem where undoing (ctrl-z) the operation works fine for single-line content, but not for multiline content.
To reproduce the issue, I have built a similar plugin which does not require the math plugin. This plugin converts text enclosed by '&' to bold text.
To reproduce this issue with an editor instance it is required to have the cursor inside a word (not after or before the end of the text, I don't know why that doesn't work, if you know why, help is appreciated^^) and paste it from the clipboard. The content will inside the '&' will be marked bold, however if you undo this operation twice, an model-position-path-incorrect-format error will be thrown.
example to paste:
aa &bb& cc
dd
ee &ff& gg
Undoing the operation twice results in this error:
Uncaught CKEditorError: model-position-path-incorrect-format {"path":[]}
Read more: https://ckeditor.com/docs/ckeditor5/latest/support/error-codes.html#error-model-position-path-incorrect-form
Unfortunately, I haven't found a way to fix this issue, and have not found a similar issue.
I know it has to do with the batches that are operated, and that maybe the position parent has to do something with it, that I should cache the position of the parent. However, I do not know how.
Below my code for an example to reproduce:
import Plugin from '#ckeditor/ckeditor5-core/src/plugin';
import Undo from '#ckeditor/ckeditor5-undo/src/undo';
import LiveRange from '#ckeditor/ckeditor5-engine/src/model/liverange';
import LivePosition from '#ckeditor/ckeditor5-engine/src/model/liveposition';
import global from '#ckeditor/ckeditor5-utils/src/dom/global';
export default class Test extends Plugin {
static get requires() {
return [Undo];
}
static get pluginName() {
return 'Test';
}
constructor(editor) {
super(editor);
this._timeoutId = null;
this._positionToInsert = null;
}
init() {
const editor = this.editor;
const modelDocument = editor.model.document;
const view = editor.editing.view;
//change < Clipboard > to < 'ClipboardPipeline' > because in version upgrade from 26 to 27
//the usage of this call changed
this.listenTo(editor.plugins.get('ClipboardPipeline'), 'inputTransformation', (evt, data) => {
const firstRange = modelDocument.selection.getFirstRange();
const leftLivePosition = LivePosition.fromPosition(firstRange.start);
leftLivePosition.stickiness = 'toPrevious';
const rightLivePosition = LivePosition.fromPosition(firstRange.end);
rightLivePosition.stickiness = 'toNext';
modelDocument.once('change:data', () => {
this._boldBetweenPositions(leftLivePosition, rightLivePosition);
leftLivePosition.detach();
rightLivePosition.detach();
}, {priority: 'high'});
});
editor.commands.get('undo').on('execute', () => {
if (this._timeoutId) {
global.window.clearTimeout(this._timeoutId);
this._timeoutId = null;
}
}, {priority: 'high'});
}
_boldBetweenPositions(leftPosition, rightPosition) {
const editor = this.editor;
const equationRange = new LiveRange(leftPosition, rightPosition);
// With timeout user can undo conversation if wants to use plain text
this._timeoutId = global.window.setTimeout(() => {
this._timeoutId = null;
let walker = equationRange.getWalker({ignoreElementEnd: true});
let nodeArray = [];
for (const node of walker) { // remember nodes, because when they are changed model-textproxy-wrong-length error occurs
nodeArray.push(node);
}
editor.model.change(writer => {
for (let node of nodeArray) {
let text = node.item.data;
if (node.item.is('$textProxy') && text !== undefined && text.match(/&/g)) {
let finishedFormulas = this._split(text);
const realRange = writer.createRange(node.previousPosition, node.nextPosition);
writer.remove(realRange);
for (let i = finishedFormulas.length - 1; i >= 0; i--) {
if (i % 2 === 0) {
writer.insertText(finishedFormulas[i], node.previousPosition);
} else {
writer.insertText(finishedFormulas[i], {bold: true}, node.previousPosition);
}
}
}
}
});
}, 100);
}
_split(text) {
let mathFormsAndText = text.split(/(&)/g);
let mathTextArray = [];
for (let i = 0; i < mathFormsAndText.length; i++) {
if (i % 4 === 0) {
mathTextArray.push(mathFormsAndText[i]);
} else if (i % 2 === 0) {
mathTextArray.push(mathFormsAndText[i]);
}
}
return mathTextArray;
}
}
Let me know if I can clarify anything.

Exception: Service invoked too many times for one day: urlfetch

I created a script in Google Sheets, which is working well but after a while I'm getting the following error:
Exception: Service invoked too many times for one day: urlfetch
I think I called the function like 200-300 times in the day, for what I checked it should be below the limit.
I read we can use cache to avoid this issue but not sure how to use it in my code.
function scrapercache(url) {
var result = [];
var description;
var options = {
'muteHttpExceptions': true,
'followRedirects': false,
};
var cache = CacheService.getScriptCache();
var properties = PropertiesService.getScriptProperties();
try {
let res = cache.get(url);
if (!res) {
// trim url to prevent (rare) errors
url.toString().trim();
var r = UrlFetchApp.fetch(url, options);
var c = r.getResponseCode();
// check for meta refresh if 200 ok
if (c == 200) {
var html = r.getContentText();
cache.put(url, "cached", 21600);
properties.setProperty(url, html);
var $ = Cheerio.load(html); // make sure this lib is added to your project!
// meta description
if ($('meta[name=description]').attr("content")) {
description = $('meta[name=description]').attr("content").trim();
}
}
result.push([description]);
}
}
catch (error) {
result.push(error.toString());
}
finally {
return result;
}
}
how can I use cache like this to enhance my script please?
var cache = CacheService.getScriptCache();
var result = cache.get(url);
if(!result) {
var response = UrlFetchApp.fetch(url);
result = response.getContentText();
cache.put(url, result, 21600);
Answer:
You can implement CacheService and PropertiesService together and only retrieve the URL again after a specified amount of time.
Code Change:
Be aware that additional calls to retrieving the cache and properties will slow your function down, especially if you are doing this a few hundred times.
As the values of the cache can be a maximum of 100 KB, we will use CacheService to keep track of which URLs are to be retrieved, but PropertiesService to store the data.
You can edit your try block as so:
var cache = CacheService.getScriptCache();
var properties = PropertiesService.getScriptProperties();
try {
let res = cache.get(url);
if (!res) {
// trim url to prevent (rare) errors
url.toString().trim();
var r = UrlFetchApp.fetch(url, options);
var c = r.getResponseCode();
// check for meta refresh if 200 ok
if (c == 200) {
var html = r.getContentText();
cache.put(url, "cached", 21600);
properties.setProperty(url, html);
var $ = Cheerio.load(html); // make sure this lib is added to your project!
// meta description
if ($('meta[name=description]').attr("content")) {
description = $('meta[name=description]').attr("content").trim();
}
}
result.push([description]);
}
}
catch (error) {
result.push(error.toString());
}
finally {
return result;
}
References:
Class CacheService | Apps Script | Google Developers
Class Cache | Apps Script | Google Developers
Class PropertiesService | Apps Script | Google Developers
Related Questions:
Service invoked too many times for one day: urlfetch

Pebble JavaScript Multiple JS Files (Pebble.js)

I'm creating a project on CloudPebble using JavaScript.
I have a "Constants.js" which hosts a variable that I would like to access using "app.js", which is the main contents of the app. However, running the app I receive the following error:
[PHONE] pebble-app.js:?: JavaScript Error:
TypeError: Cannot read property 'length' of undefined
Here is my code:
Constants.js
var mainMenuOptions = ["MenuOption1", "MenuOption2", "MenuOption3"];
app.js
var UI = require('ui');
var Vector2 = require('vector2');
var constants = require('Constants.js');
var mainMenu = new UI.Menu({
});
for (var i = 0; i < constants.mainMenuOptions.length; i++) { //Error occurs here
mainMenu.item(0, i, { title: constants.mainMenuOptions[i] });
}
...
Any help is appreciated. Thanks!
I beleive your Constants.js should have this format:
var Constants = {
mainMenuOptions: ["MenuOption1", "MenuOption2", "MenuOption3"]
};
this.exports = Constants;
And then in app.js do
var constants = require('Constants');
to access it.
Used this approach in my very first Pebble.js app Autoinsult and it worked.

Node module imported via require has no methods

I'm having a problem with node modules that I cannot resolve. I have the following three files. I've included the basic methods of interest but have excluded the rest of the methods and the actual guts of the methods.
The problem that I'm struggling with is that when the publish_event method is called on the event_queue object from events.js node crashes with the following error:
FATAL TypeError: Object # has no method 'publish_event', stack:
TypeError: Object # has no method 'publish_event'
at Events.publish_event (/Users/mburbidg/stormcloud/ccapi/cloud_pipes/node_modules/f5/server/services/event/events.js:137:15)
I cannot figure this out, you can see that I can use methods of the EventQueue object from index.js, another module, in our system just fine. I've checked names other obvious things several times.
Any suggestions as to how to proceed?
File 1 - f5/server/notifications/sqs_event_queue.js
function EventQueue() {
this.queue_name = 'notification_queue';
this.queue_url = null;
this.sqs = null;
}
EventQueue.prototype.publish_event = function(event_data, registration_id, log, callback) {
...
}
EventQueue.prototype.start = function(callback) {
...
}
module.exports = new EventQueue();
File 2 - f5/server/index.js
var event_queue = require('f5/server/notifications/sqs_event_queue');
var start_notifications = function()
{
event_queue.start(on_start);
function on_start(error)
{
}
}
File 3 - f5/server/services/event/events.js
var event_queue = require('f5/server/notifications/sqs_event_queue');
function Events () {
}
Events.prototype.publish_event = function(event_data, registration_id, log, callback) {
event_queue.publish_event(event_data, registration_id, log, callback);
};
module.exports = new Events();

How do I traverse a directory in Mozilla Firefox 4.0 and beyond?

Used to do it like this:
// Firefox 3.6 and before; Mozilla 1.9.2 and before
var ext = this.Cc["#mozilla.org/extensions/manager;1"]
.getService(this.Ci.nsIExtensionManager)
.getInstallLocation(id)
.getItemLocation(id);
// list all XML files in the installation folder:
var entries = ext.directoryEntries;
var files = [];
while(entries.hasMoreElements())
{ )
How do I get the ext variable now? I have gotten as far as the following:
Components.utils.import("resource://gre/modules/AddonManager.jsm");
AddonManager.getAddonByID(id, function(addon) {
ext = addon.getResourceURI(""); }
But not sure how to actually get the directory info to traverse it...
There might not be a directory to traverse - starting with Firefox 4 the extensions are no longer unpacked when you install them, so the resource URI will point to an XPI file (via jar: protocol scheme). Then again, in some cases the extension will be unpacked upon installation, then you will get a file:/// URI. So you should do something like this (untested):
var uri = addon.getResourceURI("");
if (uri instanceof Components.interfaces.nsIJARURI)
{
var xpiFile = uri.JARFile.QueryInterface(Components.interfaces.nsIFileURL).file;
var reader = Components.classes["#mozilla.org/libjar/zip-reader;1"]
.createInstance(Components.interfaces.nsIZipReader);
reader.init(xpiFile);
var enumerator = reader.findEntries(null);
while (enumerator.hasMoreElements())
{
var entry = enumerator.getNext().QueryInterface(Components.interfaces.nsIZipEntry);
alert(entry.name);
}
reader.close();
}
else if (uri instanceof Components.interfaces.nsIFileURL)
{
var dir = uri.file;
var enumerator = dir.directoryEntries;
while (enumerator.hasMoreElements())
{
var entry = enumerator.getNext().QueryInterface(Components.interfaces.nsIFile);
alert(entry.path);
}
}
else
throw new Error("Unexpected install location");

Resources