javascript post xml controller read xml - javascript

I would like to send an XML string as POST from javascript to server. The XML has this structure:
<?xml version="1.0" encoding="UTF-8"?>
<Devices>
<Device>
<Id>212121</Id>
<Accuracy>3</Accuracy>
<BatteryVolts>12.34</BatteryVolts>
</Device>
<Device>
<Id>212122</Id>
<Accuracy>5</Accuracy>
<BatteryVolts>12.14</BatteryVolts>
</Device>
</Devices>
In javascript I use:
var dd = '<?xml version="1.0" encoding="UTF-8"?>< ... all xml goes here '
$.ajax({
async: true,
type: "POST",
data: dd,
contentType: "application/x-www-form-urlencoded",
dataType: "xml",
url: 'api/deviceapi',
success: function (data) { var ok= 1; },
error: function (xhr) { var ok = 0; }
});
In the controller:
public int Post(object message)
{//parse message ...
return 1;
}
Once I get the xml into the controller I can parse it, no problem. Please help, thank you!

var defineClass = function () {
var inheritance = function inheritance() { };
return function defineClass(data) {
var classname = data.name,
superclass = data.extend || Object,
constructor = data.construct || function () { },
methods = data.methods || {},
statics = data.statics || {},
borrows,
provides;
if (!data.borrows) {
borrows = [];
}
else {
if (data.borrows instanceof Array) {
borrows = data.borrows;
}
else {
borrows = [data.borrows];
};
};
if (!data.provides) {
provides = [];
}
else {
if (data.provides instanceof Array) {
provides = data.provides;
}
else {
provides = [data.provides];
};
};
inheritance.prototype = superclass.prototype;
var proto = new inheritance();
for (var i = 0; i < borrows.length; i++) {
var c = borrows[i];
for (var p in c.prototype) {
if (typeof c.prototype[p] != "function") continue;
proto[p] = c.prototype[p];
}
}
for (var p in methods) {
proto[p] = methods[p];
};
proto.constructor = constructor;
constructor.superclass = superclass.prototype;
if (classname) {
proto.classname = classname;
};
for (var i = 0; i < provides.length; i++) {
var c = provides[i];
for (var p in c.prototype) {
if (typeof c.prototype[p] != "function") {
continue;
};
if (p == "constructor" || p == "superclass") {
continue;
};
if (p in proto && typeof proto[p] == "function" && proto[p].length == c.prototype[p].length) {
continue;
};
throw new Error("Class " + classname + " are not provided method " + c.classname + "." + p);
};
};
constructor.prototype = proto;
for (var p in statics) {
constructor[p] = statics[p];
};
return constructor;
}
}();
var EndPoint = (function () {
return defineClass({
name: "EndPoint",
construct: function (urlObj) {
var myUrl,
myScheme,
myDefaultScheme = "http",
myLogin,
myPassword,
myHost,
myDefaultHost = "localhost",
myIP,
myDefaultIP = "127.0.0.1",
myPort,
myDefaultPort = "80",
myPath,
myDefaultPath = "/",
myOptions,
myAnchor;
var self = this;
var parse_url = /^(?:([A-Za-z]+):)?(\/{0,3})(?:([A-Za-z]+):([A-Za-z]+)#)?([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/;
var result = parse_url.exec(urlObj);
var names = ['url', 'scheme', 'slash', 'login', 'password', 'host', 'port', 'path', 'query', 'hash'];
var i;
for (i = 0; i < names.length; i += 1) {
switch (names[i]) {
case 'url':
myUrl = result[i];
break;
case 'scheme':
myScheme = result[i];
break;
case 'slash':
break;
case 'login':
myLogin = result[i];
break;
case 'password':
myPassword = result[i];
break;
case 'host':
myHost = result[i];
break;
case 'port':
myPort = result[i];
break;
case 'path':
myPath = result[i];
break;
case 'query':
myOptions = result[i];
break;
case 'hash':
myAnchor = result[i];
break;
}
}
this.scheme = myScheme;
this.login = myLogin;
this.password = myPassword;
this.host = myHost;
this.ip = myIP;
this.port = myPort;
this.path = myPath;
this.options = myOptions;
this.anchor = myAnchor;
this.url = myUrl;
},
methods: {
ValidateIP: function (ip) {
return /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(ip);
},
ValidateUrl: function (url) {
return /^(http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,#?^=%&:\/~+#-]*[\w#?^=%&\/~+#-])?/.test(url);
},
ValidateShortUrl: function (url) {
if (/^\/\/[\w-]+(\.[\w-]+)+([\w.,#?^=%&:\/~+#-]*[\w#?^=%&\/~+#-])?/.test(url)) {
return true;
};
if (/^[\w-]+(\.[\w-]+)+([\w.,#?^=%&:\/~+#-]*[\w#?^=%&\/~+#-])?/.test(url)) {
return true;
}
return false;
}
}
})
}());
var QueryType = function QueryType() {
if (!(this instanceof QueryType)) {
return new QueryType(arguments[0]);
};
this.endPoint = arguments[0]["endPoint"];
this.envelope = arguments[0]["envelope"];
this.type = arguments[0]["type"];
this.headers = arguments[0]["headers"];
this.callback_success = arguments[0]["callback_success"];
this.callback_failure = arguments[0]["callback_failure"];
this.timeout = arguments[0]["timeout"];
this.username = arguments[0]["username"];
this.password = arguments[0]["password"];
};
var TaskManager = function () {
if (!(this instanceof TaskManager)) {
return new TaskManager();
};
var instance;
TaskManager = function () {
return instance;
};
TaskManager.prototype = this;
instance = new TaskManager();
instance.constructor = TaskManager;
function Request() {
if (!(this instanceof Request)) {
return new Request();
};
var instance;
Request = function () {
return instance;
};
Request.prototype = this;
instance = new Request();
instance.constructor = Request;
var httpRequest = new XMLHttpRequest();
instance.send = function (query, callback, errorHandler) {
try { netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); } catch (e) { };
httpRequest.abort();
if ((query.username == undefined) || (query.password == undefined)) {
httpRequest.open(query.type, query.endPoint.url, true);
}
else {
httpRequest.open(query.type, query.endPoint.url, true, query.username, query.password);
};
if (query.headers != null) {
for (var i = 0; i < query.headers.length; ++i) {
httpRequest.setRequestHeader(query.headers[i][0], query.headers[i][1]);
}
}
else {
httpRequest.setRequestHeader("SOAPAction", '""');
httpRequest.setRequestHeader("Content-Type", "text/xml");
};
httpRequest.onreadystatechange = function () {
if (httpRequest.readyState == 4) {
if (httpRequest.status == 200) {
callback(httpRequest.responseText);
}
else {
if (errorHandler) {
errorHandler(httpRequest.status, httpRequest.statusText);
}
else {
callback(null);
};
};
};
};
switch (query.type) {
case "POST":
httpRequest.send(query.envelope);
break;
case "GET":
httpRequest.send(null);
break;
}
};
instance.cancel = function () {
httpRequest.abort();
};
return instance;
};
var httpHandler = Request();
var queryQueue = [];
var timeoutID = -1;
var startedFlag = false;
var currentQuery = null;
var start = function () {
if (queryQueue.length > 0) {
startedFlag = true;
currentQuery = queryQueue.shift();
httpHandler.send(currentQuery,
function (resp) {
if (timeoutID >= 0) {
clearTimeout(timeoutID);
timeoutID = -1;
};
currentQuery.callback_success(resp);
start();
},
function (resp) {
if (timeoutID >= 0) {
clearTimeout(timeoutID);
timeoutID = -1;
};
currentQuery.callback_failure(resp);
start();
}
);
}
else {
startedFlag = false;
};
};
instance.add = function (req) {
if (req instanceof QueryType) {
queryQueue.push(req);
if (!startedFlag) {
start();
};
return true;
}
else {
return false;
};
};
instance.stopCurrent = function () {
httpHandler.cancel();
timeoutID = -1;
if ((currentQuery.callback_failure != undefined) && (currentQuery.callback_failure != null)) {
currentQuery.callback_failure("<comm_error>COMM TIMEOUT</comm_error>");
};
start();
};
return instance;
};
//to send a request it must be
TaskManager().add(
new QueryType({
"endPoint": new EndPoint("http://***.***.***.***/api/deviceapi"),
"type": "POST",
"envelope": '<?xml version="1.0" encoding="UTF-8"?>< ... all xml goes here ',
"callback_success": function (wResponse) { /* here we get a response from the server */ },
"callback_failure": function (status, statusText) { },
"timeout": 60
})
);

Related

Javascript RangeError on website proxy RangeError: Failed to construct 'Response': The status provided (0) is outside the range [200, 599]

Image Here
Hello! I am trying to add a search bar that acts like a proxy at the top of my website. Whenever I input a website like https://stackoverflow.com I receive an error on the website. RangeError: Failed to construct 'Response': The status provided (0) is outside the range [200, 599] (Note: I am using the ultraviolet service) If you'd like to test yourself the website is https://lun.netlify.app also no errors seem to appear in the console log.
importScripts('/uv/uv.bundle.js');
importScripts('/uv/uv.config.js');
class UVServiceWorker extends EventEmitter {
constructor(config = __uv$config) {
super();
if (!config.bare) config.bare = '/bare/';
this.addresses = typeof config.bare === 'string' ? [ new URL(config.bare, location) ] : config.bare.map(str => new URL(str, location));
this.headers = {
csp: [
'cross-origin-embedder-policy',
'cross-origin-opener-policy',
'cross-origin-resource-policy',
'content-security-policy',
'content-security-policy-report-only',
'expect-ct',
'feature-policy',
'origin-isolation',
'strict-transport-security',
'upgrade-insecure-requests',
'x-content-type-options',
'x-download-options',
'x-frame-options',
'x-permitted-cross-domain-policies',
'x-powered-by',
'x-xss-protection',
],
forward: [
'accept-encoding',
'connection',
'content-length',
'content-type',
'user-agent',
],
};
this.method = {
empty: [
'GET',
'HEAD'
]
};
this.statusCode = {
empty: [
204,
304,
],
};
this.config = config;
};
async fetch({ request }) {
if (!request.url.startsWith(location.origin + (this.config.prefix || '/service/'))) {
return fetch(request);
};
try {
const ultraviolet = new Ultraviolet(this.config);
if (typeof this.config.construct === 'function') {
this.config.construct(ultraviolet, 'service');
};
const db = await ultraviolet.cookie.db();
ultraviolet.meta.origin = location.origin;
ultraviolet.meta.base = ultraviolet.meta.url = new URL(ultraviolet.sourceUrl(request.url));
const requestCtx = new RequestContext(
request,
this,
ultraviolet,
!this.method.empty.includes(request.method.toUpperCase()) ? await request.blob() : null
);
if (ultraviolet.meta.url.protocol === 'blob:') {
requestCtx.blob = true;
requestCtx.base = requestCtx.url = new URL(requestCtx.url.pathname);
};
if (request.referrer && request.referrer.startsWith(location.origin)) {
const referer = new URL(ultraviolet.sourceUrl(request.referrer));
if (ultraviolet.meta.url.origin !== referer.origin && request.mode === 'cors') {
requestCtx.headers.origin = referer.origin;
};
requestCtx.headers.referer = referer.href;
};
const cookies = await ultraviolet.cookie.getCookies(db) || [];
const cookieStr = ultraviolet.cookie.serialize(cookies, ultraviolet.meta, false);
const browser = Ultraviolet.Bowser.getParser(self.navigator.userAgent).getBrowserName();
if (browser === 'Firefox' && !(request.destination === 'iframe' || request.destination === 'document')) {
requestCtx.forward.shift();
};
if (cookieStr) requestCtx.headers.cookie = cookieStr;
const reqEvent = new HookEvent(requestCtx, null, null);
this.emit('request', reqEvent);
if (reqEvent.intercepted) return reqEvent.returnValue;
const response = await fetch(requestCtx.send);
if (response.status === 500) {
return Promise.reject('');
};
const responseCtx = new ResponseContext(requestCtx, response, this);
const resEvent = new HookEvent(responseCtx, null, null);
this.emit('beforemod', resEvent);
if (resEvent.intercepted) return resEvent.returnValue;
for (const name of this.headers.csp) {
if (responseCtx.headers[name]) delete responseCtx.headers[name];
};
if (responseCtx.headers.location) {
responseCtx.headers.location = ultraviolet.rewriteUrl(responseCtx.headers.location);
};
if (responseCtx.headers['set-cookie']) {
Promise.resolve(ultraviolet.cookie.setCookies(responseCtx.headers['set-cookie'], db, ultraviolet.meta)).then(() => {
self.clients.matchAll().then(function (clients){
clients.forEach(function(client){
client.postMessage({
msg: 'updateCookies',
url: ultraviolet.meta.url.href,
});
});
});
});
delete responseCtx.headers['set-cookie'];
};
if (responseCtx.body) {
switch(request.destination) {
case 'script':
case 'worker':
responseCtx.body = `if (!self.__uv && self.importScripts) importScripts('${__uv$config.bundle}', '${__uv$config.config}', '${__uv$config.handler}');\n`;
responseCtx.body += ultraviolet.js.rewrite(
await response.text()
);
break;
case 'style':
responseCtx.body = ultraviolet.rewriteCSS(
await response.text()
);
break;
case 'iframe':
case 'document':
if (isHtml(ultraviolet.meta.url, (responseCtx.headers['content-type'] || ''))) {
responseCtx.body = ultraviolet.rewriteHtml(
await response.text(),
{
document: true ,
injectHead: ultraviolet.createHtmlInject(
this.config.handler,
this.config.bundle,
this.config.config,
ultraviolet.cookie.serialize(cookies, ultraviolet.meta, true),
request.referrer
)
}
);
};
};
};
if (requestCtx.headers.accept === 'text/event-stream') {
responseCtx.headers['content-type'] = 'text/event-stream';
};
this.emit('response', resEvent);
if (resEvent.intercepted) return resEvent.returnValue;
return new Response(responseCtx.body, {
headers: responseCtx.headers,
status: responseCtx.status,
statusText: responseCtx.statusText,
});
} catch(err) {
return new Response(err.toString(), {
status: 500,
});
};
};
getBarerResponse(response) {
const headers = {};
const raw = JSON.parse(response.headers.get('x-bare-headers'));
for (const key in raw) {
headers[key.toLowerCase()] = raw[key];
};
return {
headers,
status: +response.headers.get('x-bare-status'),
statusText: response.headers.get('x-bare-status-text'),
body: !this.statusCode.empty.includes(+response.headers.get('x-bare-status')) ? response.body : null,
};
};
get address() {
return this.addresses[Math.floor(Math.random() * this.addresses.length)];
};
static Ultraviolet = Ultraviolet;
};
self.UVServiceWorker = UVServiceWorker;
class ResponseContext {
constructor(request, response, worker) {
const { headers, status, statusText, body } = !request.blob ? worker.getBarerResponse(response) : {
status: response.status,
statusText: response.statusText,
headers: Object.fromEntries([...response.headers.entries()]),
body: response.body,
};
this.request = request;
this.raw = response;
this.ultraviolet = request.ultraviolet;
this.headers = headers;
this.status = status;
this.statusText = statusText;
this.body = body;
};
get url() {
return this.request.url;
}
get base() {
return this.request.base;
};
set base(val) {
this.request.base = val;
};
};
class RequestContext {
constructor(request, worker, ultraviolet, body = null) {
this.ultraviolet = ultraviolet;
this.request = request;
this.headers = Object.fromEntries([...request.headers.entries()]);
this.method = request.method;
this.forward = [...worker.headers.forward];
this.address = worker.address;
this.body = body || null;
this.redirect = request.redirect;
this.credentials = 'omit';
this.mode = request.mode === 'cors' ? request.mode : 'same-origin';
this.blob = false;
};
get send() {
return new Request((!this.blob ? this.address.href + 'v1/' : 'blob:' + location.origin + this.url.pathname), {
method: this.method,
headers: {
'x-bare-protocol': this.url.protocol,
'x-bare-host': this.url.hostname,
'x-bare-path': this.url.pathname + this.url.search,
'x-bare-port': this.url.port || (this.url.protocol === 'https:' ? '443' : '80'),
'x-bare-headers': JSON.stringify(this.headers),
'x-bare-forward-headers': JSON.stringify(this.forward),
},
redirect: this.redirect,
credentials: this.credentials,
mode: location.origin !== this.address.origin ? 'cors' : this.mode,
body: this.body
});
};
get url() {
return this.ultraviolet.meta.url;
};
set url(val) {
this.ultraviolet.meta.url = val;
};
get base() {
return this.ultraviolet.meta.base;
};
set base(val) {
this.ultraviolet.meta.base = val;
};
}
function isHtml(url, contentType = '') {
return (Ultraviolet.mime.contentType((contentType || url.pathname)) || 'text/html').split(';')[0] === 'text/html';
};
class HookEvent {
#intercepted;
#returnValue;
constructor(data = {}, target = null, that = null) {
this.#intercepted = false;
this.#returnValue = null;
this.data = data;
this.target = target;
this.that = that;
};
get intercepted() {
return this.#intercepted;
};
get returnValue() {
return this.#returnValue;
};
respondWith(input) {
this.#returnValue = input;
this.#intercepted = true;
};
};
var R = typeof Reflect === 'object' ? Reflect : null
var ReflectApply = R && typeof R.apply === 'function'
? R.apply
: function ReflectApply(target, receiver, args) {
return Function.prototype.apply.call(target, receiver, args);
}
var ReflectOwnKeys
if (R && typeof R.ownKeys === 'function') {
ReflectOwnKeys = R.ownKeys
} else if (Object.getOwnPropertySymbols) {
ReflectOwnKeys = function ReflectOwnKeys(target) {
return Object.getOwnPropertyNames(target)
.concat(Object.getOwnPropertySymbols(target));
};
} else {
ReflectOwnKeys = function ReflectOwnKeys(target) {
return Object.getOwnPropertyNames(target);
};
}
function ProcessEmitWarning(warning) {
if (console && console.warn) console.warn(warning);
}
var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {
return value !== value;
}
function EventEmitter() {
EventEmitter.init.call(this);
}
EventEmitter.EventEmitter = EventEmitter;
EventEmitter.prototype._events = undefined;
EventEmitter.prototype._eventsCount = 0;
EventEmitter.prototype._maxListeners = undefined;
var defaultMaxListeners = 10;
function checkListener(listener) {
if (typeof listener !== 'function') {
throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
}
}
Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
enumerable: true,
get: function() {
return defaultMaxListeners;
},
set: function(arg) {
if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {
throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.');
}
defaultMaxListeners = arg;
}
});
EventEmitter.init = function() {
if (this._events === undefined ||
this._events === Object.getPrototypeOf(this)._events) {
this._events = Object.create(null);
this._eventsCount = 0;
}
this._maxListeners = this._maxListeners || undefined;
};
EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {
throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.');
}
this._maxListeners = n;
return this;
};
function _getMaxListeners(that) {
if (that._maxListeners === undefined)
return EventEmitter.defaultMaxListeners;
return that._maxListeners;
}
EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
return _getMaxListeners(this);
};
EventEmitter.prototype.emit = function emit(type) {
var args = [];
for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);
var doError = (type === 'error');
var events = this._events;
if (events !== undefined)
doError = (doError && events.error === undefined);
else if (!doError)
return false;
if (doError) {
var er;
if (args.length > 0)
er = args[0];
if (er instanceof Error) {
throw er;
}
var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));
err.context = er;
throw err;
}
var handler = events[type];
if (handler === undefined)
return false;
if (typeof handler === 'function') {
ReflectApply(handler, this, args);
} else {
var len = handler.length;
var listeners = arrayClone(handler, len);
for (var i = 0; i < len; ++i)
ReflectApply(listeners[i], this, args);
}
return true;
};
function _addListener(target, type, listener, prepend) {
var m;
var events;
var existing;
checkListener(listener);
events = target._events;
if (events === undefined) {
events = target._events = Object.create(null);
target._eventsCount = 0;
} else {
if (events.newListener !== undefined) {
target.emit('newListener', type,
listener.listener ? listener.listener : listener);
events = target._events;
}
existing = events[type];
}
if (existing === undefined) {
existing = events[type] = listener;
++target._eventsCount;
} else {
if (typeof existing === 'function') {
existing = events[type] =
prepend ? [listener, existing] : [existing, listener];
} else if (prepend) {
existing.unshift(listener);
} else {
existing.push(listener);
}
// Check for listener leak
m = _getMaxListeners(target);
if (m > 0 && existing.length > m && !existing.warned) {
existing.warned = true;
var w = new Error('Possible EventEmitter memory leak detected. ' +
existing.length + ' ' + String(type) + ' listeners ' +
'added. Use emitter.setMaxListeners() to ' +
'increase limit');
w.name = 'MaxListenersExceededWarning';
w.emitter = target;
w.type = type;
w.count = existing.length;
ProcessEmitWarning(w);
}
}
return target;
}
EventEmitter.prototype.addListener = function addListener(type, listener) {
return _addListener(this, type, listener, false);
};
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
EventEmitter.prototype.prependListener =
function prependListener(type, listener) {
return _addListener(this, type, listener, true);
};
function onceWrapper() {
if (!this.fired) {
this.target.removeListener(this.type, this.wrapFn);
this.fired = true;
if (arguments.length === 0)
return this.listener.call(this.target);
return this.listener.apply(this.target, arguments);
}
}
function _onceWrap(target, type, listener) {
var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };
var wrapped = onceWrapper.bind(state);
wrapped.listener = listener;
state.wrapFn = wrapped;
return wrapped;
}
EventEmitter.prototype.once = function once(type, listener) {
checkListener(listener);
this.on(type, _onceWrap(this, type, listener));
return this;
};
EventEmitter.prototype.prependOnceListener =
function prependOnceListener(type, listener) {
checkListener(listener);
this.prependListener(type, _onceWrap(this, type, listener));
return this;
};
EventEmitter.prototype.removeListener =
function removeListener(type, listener) {
var list, events, position, i, originalListener;
checkListener(listener);
events = this._events;
if (events === undefined)
return this;
list = events[type];
if (list === undefined)
return this;
if (list === listener || list.listener === listener) {
if (--this._eventsCount === 0)
this._events = Object.create(null);
else {
delete events[type];
if (events.removeListener)
this.emit('removeListener', type, list.listener || listener);
}
} else if (typeof list !== 'function') {
position = -1;
for (i = list.length - 1; i >= 0; i--) {
if (list[i] === listener || list[i].listener === listener) {
originalListener = list[i].listener;
position = i;
break;
}
}
if (position < 0)
return this;
if (position === 0)
list.shift();
else {
spliceOne(list, position);
}
if (list.length === 1)
events[type] = list[0];
if (events.removeListener !== undefined)
this.emit('removeListener', type, originalListener || listener);
}
return this;
};
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
EventEmitter.prototype.removeAllListeners =
function removeAllListeners(type) {
var listeners, events, i;
events = this._events;
if (events === undefined)
return this;
if (events.removeListener === undefined) {
if (arguments.length === 0) {
this._events = Object.create(null);
this._eventsCount = 0;
} else if (events[type] !== undefined) {
if (--this._eventsCount === 0)
this._events = Object.create(null);
else
delete events[type];
}
return this;
}
if (arguments.length === 0) {
var keys = Object.keys(events);
var key;
for (i = 0; i < keys.length; ++i) {
key = keys[i];
if (key === 'removeListener') continue;
this.removeAllListeners(key);
}
this.removeAllListeners('removeListener');
this._events = Object.create(null);
this._eventsCount = 0;
return this;
}
listeners = events[type];
if (typeof listeners === 'function') {
this.removeListener(type, listeners);
} else if (listeners !== undefined) {
// LIFO order
for (i = listeners.length - 1; i >= 0; i--) {
this.removeListener(type, listeners[i]);
}
}
return this;
};
function _listeners(target, type, unwrap) {
var events = target._events;
if (events === undefined)
return [];
var evlistener = events[type];
if (evlistener === undefined)
return [];
if (typeof evlistener === 'function')
return unwrap ? [evlistener.listener || evlistener] : [evlistener];
return unwrap ?
unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
}
EventEmitter.prototype.listeners = function listeners(type) {
return _listeners(this, type, true);
};
EventEmitter.prototype.rawListeners = function rawListeners(type) {
return _listeners(this, type, false);
};
EventEmitter.listenerCount = function(emitter, type) {
if (typeof emitter.listenerCount === 'function') {
return emitter.listenerCount(type);
} else {
return listenerCount.call(emitter, type);
}
};
EventEmitter.prototype.listenerCount = listenerCount;
function listenerCount(type) {
var events = this._events;
if (events !== undefined) {
var evlistener = events[type];
if (typeof evlistener === 'function') {
return 1;
} else if (evlistener !== undefined) {
return evlistener.length;
}
}
return 0;
}
EventEmitter.prototype.eventNames = function eventNames() {
return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];
};
function arrayClone(arr, n) {
var copy = new Array(n);
for (var i = 0; i < n; ++i)
copy[i] = arr[i];
return copy;
}
function spliceOne(list, index) {
for (; index + 1 < list.length; index++)
list[index] = list[index + 1];
list.pop();
}
function unwrapListeners(arr) {
var ret = new Array(arr.length);
for (var i = 0; i < ret.length; ++i) {
ret[i] = arr[i].listener || arr[i];
}
return ret;
}
function once(emitter, name) {
return new Promise(function (resolve, reject) {
function errorListener(err) {
emitter.removeListener(name, resolver);
reject(err);
}
function resolver() {
if (typeof emitter.removeListener === 'function') {
emitter.removeListener('error', errorListener);
}
resolve([].slice.call(arguments));
};
eventTargetAgnosticAddListener(emitter, name, resolver, { once: true });
if (name !== 'error') {
addErrorHandlerIfEventEmitter(emitter, errorListener, { once: true });
}
});
}
function addErrorHandlerIfEventEmitter(emitter, handler, flags) {
if (typeof emitter.on === 'function') {
eventTargetAgnosticAddListener(emitter, 'error', handler, flags);
}
}
function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
if (typeof emitter.on === 'function') {
if (flags.once) {
emitter.once(name, listener);
} else {
emitter.on(name, listener);
}
} else if (typeof emitter.addEventListener === 'function') {
emitter.addEventListener(name, function wrapListener(arg) {
if (flags.once) {
emitter.removeEventListener(name, wrapListener);
}
listener(arg);
});
} else {
throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof emitter);
}
}

Uncaught TypeError: map.downloadExport is not a function (angular 2 typescript)

Im getting the following error in my typescript class and cannot understand why. All I am doing is trying to call a helper function passing the token.
Error: post error: map.downloadExport is not a function
here is my code
import {Component, ViewEncapsulation} from '#angular/core';
import {MapService} from "../../../shared/leaflet/map.service";
import {GeocodingService} from "../../../shared/leaflet/geocoding.service";
import "leaflet-easybutton";
var leafletImage = require("leaflet-image/leaflet-image")
declare var downloadExport: any;
// import '../../../../leaflet_export.js';
#Component({
encapsulation: ViewEncapsulation.None,
selector: 'Home',
templateUrl: './app/components/tools/sketch/sketch.component.html',
styleUrls: [ './app/components/tools/sketch/sketch.component.css' ],
providers: [MapService, GeocodingService]
})
export class SketchComponent {
public vtLayer:any;
constructor(private mapService: MapService, private geocoder: GeocodingService) {}
ngOnInit(): void {
console.log('tools component');
}
ngAfterViewInit() {
let map = L.map("map", {
zoomControl: false,
center: L.latLng(4.418294, 108.224145),
zoom: 6,
minZoom: 4,
maxZoom:22,
layers: [this.mapService.baseMaps.OpenStreetMap]
}).setView([3.1466, 101.6958], 6);
L.control.zoom({ position: "topright" }).addTo(map);
L.control.scale().addTo(map);
var customControl = L.Control.extend({
options: {
position: 'bottomright'
},
map.addControl(new customControl());
this.mapService.map = map;
this.geocoder.getCurrentLocation()
.subscribe(
location => map.panTo([location.latitude, location.longitude]),
err => console.error(err)
);
toolbar
var drawnItems = L.featureGroup();
map.addLayer(drawnItems);
var drawControl = new L.Control.Draw(options);
map.addControl(drawControl);
map.on(L.Draw.Event.CREATED, function(e:any) {
var layer = e.layer;
drawnItems.addLayer(layer);
});
function afterRender(result:any) {
return result;
}
function afterExport(result:any) {
return result;
}
function downloadMap(caption:any) {
var downloadOptions = {
caption: {
text: caption,
font: '30px Arial',
fillStyle: 'black',
position: [100,200]
},
exclude: ['.leaflet-control-zoom', '.leaflet-control-attribution'],
format: 'image/jpeg',
fileName: 'Map.jpg',
afterRender: afterRender,
afterExport: afterExport
};
var promise = map.downloadExport(downloadOptions);
var data = promise.then(function(result:any){
return result;
});
console.log(data)
}
}
}
and this is my JS file
L.Map.mergeOptions({ preferCanvas: true });
if (!('exportError' in this)) {
this.exportError = {
wrongBeginSelector:,
wrongEndSelector: ,
jqueryNotAvailable: ,
popupWindowBlocked: ,
emptyFilename:
};
}
this.supportedCanvasMimeTypes = function() {
if ('_supportedCanvasMimeTypes' in this) {
return this._supportedCanvasMimeTypes;
}
var mimeTypes = {
PNG:'image/png',
JPEG: 'image/jpeg',
JPG: 'image/jpg',
GIF: 'image/gif',
BMP: 'image/bmp',
TIFF: 'image/tiff',
XICON: 'image/x-icon',
SVG: 'image/svg+xml',
WEBP: 'image/webp'
};
var canvas = document.createElement('canvas');
canvas.style.display = 'none';
canvas = document.body.appendChild(canvas);
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'red';
ctx.fillRect(0,0,1,1);
this._supportedCanvasMimeTypes = {};
for (var type in mimeTypes) {
var mimeType = mimeTypes[type];
var data = canvas.toDataURL(mimeType);
var actualType = data.replace(/^data:([^;]*).*/, '$1');
if (mimeType === actualType) {
this._supportedCanvasMimeTypes[type] = mimeType;
}
}
document.body.removeChild(canvas);
return this._supportedCanvasMimeTypes;
};
this.export = function(options){
var caption = {};
var exclude = [];
var format ='image/png';
options = options || { caption: {}, exclude: []};
if ('caption' in options) {
caption = options['caption'];
if ('position' in caption) {
var position = caption.position;
if (!Array.isArray(position)) {
position = [0, 0];
}
if (position.length !=2 ) {
if (position.length === 0){
position[0] = 0;
}
if (position.length === 1 ) {
position[1] = 0;
}
}
if (typeof position[0] !== 'number') {
if (typeof position[0] === 'string') {
position[0] = parseInt(position[0]);
if (isNaN(position[0])) {
position[0] = 0;
}
}
}
if (typeof position[1] !== 'number') {
if (typeof position[1] === 'string') {
position[1] = parseInt(position[1]);
if (isNaN(position[1])) {
position[1] = 0;
}
}
}
caption.position = position;
}
}
if ('exclude' in options && Array.isArray(options['exclude'])) {
exclude = options['exclude'];
}
if ('format' in options) {
format = options['format'];
}
var afterRender = options.afterRender;
if (typeof afterRender !== 'function') {
afterRender = function(result) {return result};
}
var afterExport = options.afterExport;
if (typeof afterExport !== 'function') {
afterExport = function(result) {return result};
}
var container = options.container || this._container;
var hide = [];
for (var i = 0; i < exclude.length; i++) {
var selector = exclude[i];
switch (typeof selector) {
case 'object':
if ('tagName' in selector) { //DOM element
hide.push(selector);
}
break;
case 'string': //selector
var type = selector.substr(0,1);
switch (type) {
case '.': //class selector
// var elements = container.getElementsByClassName(selector.substr(1));
// for (var j = 0; j < elements.length; j++) {
// hide.push(elements.item(j));
// }
break;
case '#': //id selector
var element = container.getElementById(selector.substr(1));
if (element) {
hide.push(element);
}
break;
case '$': //JQuery
var jQuerySelector = selector.trim().substr(1);
if (jQuerySelector.substr(0,1) !== '(') {
throw new Error(this.exportError.wrongBeginSelector);
}
jQuerySelector = jQuerySelector.substr(1);
if (jQuerySelector.substr(-1) !== ')') {
throw new Error(this.exportError.wrongEndSelector);
}
jQuerySelector = jQuerySelector.substr(0, jQuerySelector.length-1);
if (typeof jQuery !== 'undefined') {
var elements = $(jQuerySelector, container);
for (var j = 0; j < elements.length; j++) {
hide.push(elements[i]);
}
} else {
throw new Error(this.exportError.jqueryNotAvailable);
}
}
}
}
for (var i = 0; i < hide.length; i++) { //Hide exclude elements
hide[i].setAttribute('data-html2canvas-ignore', 'true');
}
var _this = this;
return html2canvas(container, {
useCORS: true
}).then(afterRender).then(
function(canvas) {
for (var i = 0; i < hide.length; i++) { //Unhide exclude elements
hide[i].removeAttribute('data-html2canvas-ignore');
}
if ('text' in caption && caption.text) {
var x, y;
if ('position' in caption) {
x = caption.position[0];
y = caption.position[1];
} else {
x = 0;
y = 0;
}
var ctx = canvas.getContext('2d');
if ('font' in caption) {
ctx.font = caption.font;
}
if ('fillStyle' in caption) {
ctx.fillStyle = caption.fillStyle;
}
ctx.fillText(caption.text,x , y);
}
// document.body.appendChild(canvas);
var ret = format === 'canvas' ? canvas : { data:canvas.toDataURL(format), width: canvas.width, height: canvas.height, type: format};
return ret;
}, function(reason) {
var newReason = reason;
alert(reason);
}).then(afterExport)
;
};
this.printExport = function(options) {
var _this = this;
return this.export(options).then(
function(result) {
var printWindow = window.open('', '_blank');
if (printWindow) {
var printDocument = printWindow.document;
printDocument.write('<html><head><title>' + (options.text ? options.text : '') + '</title></head><body onload=\'window.print(); window.close();\'></body></html>');
var img = printDocument.createElement('img');
img.height = result.height;
img.width = result.width;
img.src = result.data;
printDocument.body.appendChild(img);
printDocument.close();
printWindow.focus();
} else {
throw new Error(_this.exportError.popupWindowBlocked);
}
return result;
}
);
};
this.downloadExport = function(options) {
if (!('fileName' in options)) {
throw new Error(this.exportError.emptyFilename);
}
var fileName = options.fileName;
delete options.fileName;
return this.export(options).then(
function(result) {
var fileData = atob(result.data.split(',')[1]);
var arrayBuffer = new ArrayBuffer(fileData.length);
var view = new Uint8Array(arrayBuffer);
for (var i = 0; i < fileData.length; i++) {
view[i] = fileData.charCodeAt(i) & 0xff;
}
var blob;
if (typeof Blob === 'function') {
blob = new Blob([arrayBuffer], { type: 'application/octet-stream' });
} else {
var blobBuilder = new (window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder);
blobBuilder.append(arrayBuffer);
blob = blobBuilder.getBlob('application/octet-stream');
}
if (window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveBlob(blob, fileName);
} else {
var blobUrl = (window.URL || window.webkitURL).createObjectURL(blob);
var downloadLink = document.createElement('a');
downloadLink.style = 'display: none';
downloadLink.download = fileName;
downloadLink.href = blobUrl;
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
}
return result;
}
);
};

Send object this to functions that take No-arguments

How can i send parameter this to function.
Above options work in constructor :
selectors[i].onblur = this.validation;
But if in function Valid i call the selectors[i].validation, above solution will not working. Does Somebody know, how to call selectors[i].validation with parameter this??
For any help, i will be very grateful.
link to demo:
http://codepen.io/anon/pen/YqryVr
My js classes:
var Validator = (function () {
var errorClassName = "error";
var selectors;
var regexMap;
function Validator(id, regexObject) {
if (id === void 0) { id = "form"; }
regexMap = regexObject.getMap();
selectors = document.getElementById(id).elements;
for (i = 0; i < selectors.length; ++i) {
selectors[i].onblur = this.validation;
}
};
Validator.prototype.setErrorClassName = function (className) {
errorClassName = className;
};
Validator.prototype.addClass = function (selector) {
if(selector.className.indexOf(errorClassName) < 1)
selector.className += " " + errorClassName;
};
Validator.prototype.removeClass = function (selector) {
selector.className = selector.className.replace(errorClassName, '');
};
Validator.prototype.validation = function () {
alert('this.type: ' + this.type);
switch(this.type) {
case 'textarea':
case 'text':
if(this.dataset.regex in regexMap) this.dataset.regex = regexMap[this.dataset.regex];
var pattern = new RegExp(this.dataset.regex);
if(this.value.length !== 0 && pattern.test(this.value)) {
Validator.prototype.removeClass(this);
return true;
} else {
Validator.prototype.addClass(this);
return false;
}
break;
case 'select-one':
if(this.value.length === 0) {
Validator.prototype.addClass(this);
return false;
} else {
Validator.prototype.removeClass(this);
return true;
}
break;
}
return true;
};
Validator.prototype.valid = function () {
for (i = 0; i < selectors.length; ++i) {
selectors[i].validation;
}
return true;
};
return Validator;
}());
var SelectorAttribute = (function () {
function SelectorAttribute(name, regex) {
this.name = name;
this.regex = regex;
}
SelectorAttribute.prototype.toString = function () {
return "name: " + this.name + ", regex = " + this.regex;
};
return SelectorAttribute;
}());
var StandardRegexPatterns = (function () {
var map = {};
function StandardRegexPatterns() {
map['zip-code-poland'] = '^[0-9]{2}-[0-9]{3}$';
map['phone-number-poland'] = '^[0-9]{9}$';
map['digits'] = '^[0-9]+$';
map['alpha'] = '^[a-zA-z]+$';
map['email'] = '^[-a-z0-9~!$%^&*_=+}{\'?]+(\.[-a-z0-9~!$%^&*_=+}{\'?]+)*#([a-z0-9_][-a-z0-9_]*(\.[-a-z0-9_]+)*\.(aero|arpa|biz|com|coop|edu|gov|info|int|mil|museum|name|net|org|pro|travel|mobi|[a-z][a-z])|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,5})?';
map['login'] = '^[a-z0-9_-\.]{3,21}$';
map['ip-address'] = '^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$';
map['url-address'] = '^((http[s]?|ftp):\/)?\/?([^:\/\s]+)((\/\w+)*\/)([\w\-\.]+[^#?\s]+)(.*)?(#[\w\-]+)?$';
}
StandardRegexPatterns.prototype.getMap = function () {
return map;
};
return StandardRegexPatterns;
}());
$( document ).ready(function() {
var validator = new Validator('form', new StandardRegexPatterns());
validator.setErrorClassName("error");
//var pattern = new StandardRegexPatterns();
// alert(Object.keys(pattern.getMap()));
$("button").on('click', function(){
alert(validator.valid());
});
});
You can use the following:
functionname.apply(this, [arguments]);
or
functionname.call(this, argument1, argument2);
if you don't have arguments you can just omit them.
I usually just do this:
funcitonname.apply(this, Arguments);
if I'm calling this method from within a function already so I can carry on the arguments to the functionname().
Learn more about apply
Learn more about call

Uncaught TypeError: Cannot read property 'options' of null

I cannot figure out why I keep getting this error:
Uncaught TypeError: Cannot read property 'options' of null
getFSREPlist
(anonymous function)
The error is referencing this line of code (21):
document.getElementById(elementidupdate).options.length=0;
What is weird is that it was working prior to this new google map api I just put on. Also, it is pulling the country code "1" and putting it in the drop down, but not the province code "19".
Here is the on page script:
getFSREPlist('1', 'fsrep-search-province', 'CountryID', '19');getFSREPlist('19', 'fsrep-search-city', 'ProvinceID', '3'); request.send(null);
Here is the full file:
function sack(file) {
this.xmlhttp = null;
this.resetData = function () {
this.method = "POST";
this.queryStringSeparator = "?";
this.argumentSeparator = "&";
this.URLString = "";
this.encodeURIString = true;
this.execute = false;
this.element = null;
this.elementObj = null;
this.requestFile = file;
this.vars = new Object();
this.responseStatus = new Array(2);
};
this.resetFunctions = function () {
this.onLoading = function () {};
this.onLoaded = function () {};
this.onInteractive = function () {};
this.onCompletion = function () {};
this.onError = function () {};
this.onFail = function () {};
};
this.reset = function () {
this.resetFunctions();
this.resetData();
};
this.createAJAX = function () {
try {
this.xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e1) {
try {
this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e2) {
this.xmlhttp = null;
}
}
if (!this.xmlhttp) {
if (typeof XMLHttpRequest != "undefined") {
this.xmlhttp = new XMLHttpRequest();
} else {
this.failed = true;
}
}
};
this.setVar = function (name, value) {
this.vars[name] = Array(value, false);
};
this.encVar = function (name, value, returnvars) {
if (true == returnvars) {
return Array(encodeURIComponent(name), encodeURIComponent(value));
} else {
this.vars[encodeURIComponent(name)] = Array(encodeURIComponent(value), true);
}
}
this.processURLString = function (string, encode) {
encoded = encodeURIComponent(this.argumentSeparator);
regexp = new RegExp(this.argumentSeparator + "|" + encoded);
varArray = string.split(regexp);
for (i = 0; i < varArray.length; i++) {
urlVars = varArray[i].split("=");
if (true == encode) {
this.encVar(urlVars[0], urlVars[1]);
} else {
this.setVar(urlVars[0], urlVars[1]);
}
}
}
this.createURLString = function (urlstring) {
if (this.encodeURIString && this.URLString.length) {
this.processURLString(this.URLString, true);
}
if (urlstring) {
if (this.URLString.length) {
this.URLString += this.argumentSeparator + urlstring;
} else {
this.URLString = urlstring;
}
}
this.setVar("rndval", new Date().getTime());
urlstringtemp = new Array();
for (key in this.vars) {
if (false == this.vars[key][1] && true == this.encodeURIString) {
encoded = this.encVar(key, this.vars[key][0], true);
delete this.vars[key];
this.vars[encoded[0]] = Array(encoded[1], true);
key = encoded[0];
}
urlstringtemp[urlstringtemp.length] = key + "=" + this.vars[key][0];
}
if (urlstring) {
this.URLString += this.argumentSeparator + urlstringtemp.join(this.argumentSeparator);
} else {
this.URLString += urlstringtemp.join(this.argumentSeparator);
}
}
this.runResponse = function () {
eval(this.response);
}
this.runAJAX = function (urlstring) {
if (this.failed) {
this.onFail();
} else {
this.createURLString(urlstring);
if (this.element) {
this.elementObj = document.getElementById(this.element);
}
if (this.xmlhttp) {
var self = this;
if (this.method == "GET") {
totalurlstring = this.requestFile + this.queryStringSeparator + this.URLString;
this.xmlhttp.open(this.method, totalurlstring, true);
} else {
this.xmlhttp.open(this.method, this.requestFile, true);
try {
this.xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
} catch (e) {}
}
this.xmlhttp.onreadystatechange = function () {
switch (self.xmlhttp.readyState) {
case 1:
self.onLoading();
break;
case 2:
self.onLoaded();
break;
case 3:
self.onInteractive();
break;
case 4:
self.response = self.xmlhttp.responseText;
self.responseXML = self.xmlhttp.responseXML;
self.responseStatus[0] = self.xmlhttp.status;
self.responseStatus[1] = self.xmlhttp.statusText;
if (self.execute) {
self.runResponse();
}
if (self.elementObj) {
elemNodeName = self.elementObj.nodeName;
elemNodeName.toLowerCase();
if (elemNodeName == "input" || elemNodeName == "select" || elemNodeName == "option" || elemNodeName == "textarea") {
self.elementObj.value = self.response;
} else {
self.elementObj.innerHTML = self.response;
}
}
if (self.responseStatus[0] == "200") {
self.onCompletion();
} else {
self.onError();
}
self.URLString = "";
break;
}
};
this.xmlhttp.send(this.URLString);
}
}
};
this.reset();
this.createAJAX();
}
var ajax = new Array();
function getFSREPlist(sel, elementidupdate, fsrepvariable, currentvalue) {
if (sel == '[object]' || sel == '[object HTMLSelectElement]') {
var FSREPID = sel.options[sel.selectedIndex].value;
} else {
var FSREPID = sel;
}
document.getElementById(elementidupdate).options.length = 0;
var index = ajax.length;
ajax[index] = new sack();
ajax[index].requestFile = 'http://www.cabcot.com/wp-content/plugins/firestorm-real-estate-plugin/search.php?' + fsrepvariable + '=' + FSREPID + '&cvalue=' + currentvalue;
ajax[index].onCompletion = function () {
ElementUpdate(index, elementidupdate)
};
ajax[index].runAJAX();
}
function ElementUpdate(index, elementidupdate) {
var obj = document.getElementById(elementidupdate);
eval(ajax[index].response);
}
You should call getFSREPlist when DOM is loaded. I ran
document.getElementById('fsrep-search-province').options.length=0
from chrome´s console. while page was still loading and caused that same error.
http://i.imgur.com/GBFizq1.png

Javascript Array indexFirst

I build a prototype that handle pages, I successfully add (push), but can get the data, I failed:
var foundImageIndex = Pages.indexFirst(function (item) { if (item.PageID == PageID) return true; });
Here the javascript page handler:
var Pages = new Array();
PageContainer = function () //constructor for the proxy
{
// this._baseURL = url;
};
PageContainer.prototype =
{
AddPage: function (data) {
if (data == null) return;
Pages.push({ PageID: data.PageID, SegmentID: data.SegmentID });
},
GetPage: function (PageID) {
alert('getPage('+PageID+')=' + JSON.stringify(Pages));
var foundImageIndex = Pages.indexFirst(function (item) { if (item.PageID == PageID) return true; });
var dt = { PageID: Pages[foundImageIndex].PageID, SegmentID: Pages[foundImageIndex].SegmentID };
return dt;
}
};
I call from other js as following:
var gPageContainer = new PageContainer();
for (var i = 0; i < SegStruct.SegmentsCount; i++) {
var segRClass = //get from webservice
gPageContainer.AddPage({ PageID: i, SegmentID: segRClass.SegmentID });
}
I trying to call: gPageContainer.GetPage(1); but it failed in GetPage: function (PageID) it returns -1 in:
var foundImageIndex = Pages.indexFirst(function (item) { if (item.PageID == PageID) return true; });
foundImageIndex always -1
why?
Simply add the following before the constructor:
if (typeof Array.prototype.indexFirst == 'undefined') {
Array.prototype.indexFirst = function (validator) {
for (var i = 0; i <= this.length - 1; i++) {
if (validator(this[i])) {
return i;
}
}
return -1;
};
}

Categories