Error while executing async get of Outlook item property - javascript

Why am I getting Could not complete the operation due to error 80043200 sometimes while getting Outlook item property (for example, Subject) in email Compose mode?
Call stack:
Error
at n.prototype.execute (appsforoffice.microsoft.com/lib/1.1/hosted/outlook-win32-16.02.js:11:86635)
at u.DDA.OutlookAppOm.prototype.callOutlookDispatcher (appsforoffice.microsoft.com/lib/1.1/hosted/outlook-win32-16.02.js:11:150300)
at u.DDA.OutlookAppOm.prototype.invokeHostMethod (appsforoffice.microsoft.com/lib/1.1/hosted/outlook-win32-16.02.js:11:150169)
at u.DDA.OutlookAppOm.prototype._standardInvokeHostMethod$i$0 (appsforoffice.microsoft.com/lib/1.1/hosted/outlook-win32-16.02.js:11:148443)
at r.ComposeSubject.prototype.getAsync (appsforoffice.microsoft.com/lib/1.1/hosted/outlook-win32-16.02.js:11:190544)
We use following code for getting a field from an Outlook item:
sfMailApp.OfficeManager.prototype._reloadField = function (name, defaultValue) {
var deferred = $.Deferred();
defaultValue = defaultValue || '';
var item = this.getItem();
if (item.isFake) {
deferred.resolve('');
return deferred.promise();
}
var field = item[name];
if (field && this._isComposeMode && field.getAsync) {
var _this = this;
try {
field.getAsync(function (result) {
if (result.status === Office.AsyncResultStatus.Succeeded) {
_this[name] = _this._processOfficeData(result.value) || defaultValue;
deferred.resolve(_this[name]);
}
else {
_this._onError(result);
deferred.reject();
}
});
} catch (e) {
deferred.reject();
}
} else {
this[name] = this._processOfficeData(field) || defaultValue;
deferred.resolve(this[name]);
}
return deferred.promise();}
Code for getItem function:
sfMailApp.OfficeManager.prototype.getItem = function () {
var item = Office && Office.context && Office.context.mailbox && Office.context.mailbox.item ? Office.context.mailbox.item : null;
if (!item) {
item = {
isFake: true
}
}
return item;}
One more error we're getting sometimes while trying to get user identity token:
{"name":"AccessRestricted","message":"Internal protocol error: -2147467259'.","code":9017 }
How should we handle that?

Related

Wait for invocation/method to return a value in javascript signalr

I can't figure why my code doesn't wait for the invocation to return a value.
Tried making it into a separate function, still the same error.
It looks like I just can't access .done function.
Main Code
JS:
var connection = new signalR.HubConnectionBuilder().withUrl("/rouletteHub").build();
function HandleBet(event, color){
var amount = parseInt(document.getElementById("amount").value);
var actualPoints = 0;
connection.invoke("GetPtsFromServer").then(function (pts) {
actualPoints = parseInt(pts);
})
console.log(actualPoints);
if (isNaN(amount)){
ErrorNotANumber();
return;
}
if (amount < 0){
ErrorNegativeNumber();
return;
}
//console.log(amount);
//console.log(actualPoints)
if (amount > actualPoints){
NotEnoughPoints();
return;
}
if (amount > 0){
connection.invoke("PlaceBet", color.toString(), amount).then(function () {
PlacedBetSuccess(GetColor2(color), amount);
}, function (err) {
PlacedBetError();
})
}
event.preventDefault();
}
C#:
public int? GetPtsFromServer()
{
if (Context.User?.Identity != null && !Context.User.Identity.IsAuthenticated) return null;
if (Context.User == null) return null;
var dcId = Context.User.Claims.FirstOrDefault(c => c.Type == "urn:discord:id")?.Value;
return DataWrapper.HelpForTypes.GetPts(Convert.ToUInt64(dcId));
}
When using .done instead of .then it throws an error
Console:
Uncaught TypeError: connection.invoke(...).done is not a function
at HandleBet (Roulette:420)
at HTMLButtonElement.<anonymous> (Roulette:469)
JS:
connection.invoke("GetPtsFromServer").done(function (pts) {
actualPoints = parseInt(pts);
});
Fixed by making HandleBet async and inserting await before connection.invoke.

KnockoutJS: issues validating multiple rows with dropdownlists

So I'm trying validate the two dropdowns that I have on button click. When the dropdowns first initiate, they are initiated with a value of undefined because nothing has been selected. This is what I want. But when I click the add button to validate the dropdowns before I add another row, the validation never occurs.
JS
ko.validation.init({
insertMessages: false,
errorMessageClass: "ErrorLine"
});
ko.validation.rules['bothUndefined'] = {
getValue: function (o) {
return (typeof o === 'function' ? o() : o);
},
validator: function (val, params) {
var self = this;
var anyOne = ko.utils.arrayForEach(params, function (param) {
if (typeof param === "function") {
return typeof param() === "undefined";
} else {
return (typeof param === "undefined");
}
});
return (typeof anyOne !== "undefined");
},
message: 'Please select one change.'
};
ko.validation.registerExtenders();
function BookPossessionTransferVM() {
var self = this;
.
.
.
self.PossessionChanges = ko.observableArray([]);
self.PossessionChangesErrors = ko.validation.group(self.PossessionChanges(), { deep: true, live: true });
self.PossessionChanges.push(new PossessionChangeVM(self.PossessionChanges().length +1))
.
.
.
self.addPossessionChange = function () {
if (self.PossessionChanges().length < 1) {
self.PossessionChanges.push(new PossessionChangesVM(self.PossessionChanges().length + 1,
self.AllFrom()));
} else {
self.PossessionChangesErrors.showAllMessages();
}
}
}
function PossessionChangeVM(possessionChangeId) {
var self = this;
self.possessionChangeId = ko.observable(possessionChangeId);
self.SelectedFrom = ko.validatedObservable();
self.SelectedTo = ko.validatedObservable();
self.IsValidRow = ko.pureComputed(function() {
return typeof self.SelectedFrom !== "undefined" && typeof self.SelectedTo !== "undefined";
}).extend({
bothUndefined: {
params: [self.SelectedFrom, self.SelectedTo]
}
});
self.ChangeType = ko.pureComputed(function() {
if (self.SelectedFrom() !== undefined && self.SelectedTo() !== undefined) {
return 'Update';
} else if (self.SelectedFrom() === undefined && self.SelectedTo() === undefined) {
return '';
} else if (self.SelectedFrom() === undefined) {
return 'Add';
} else if (self.SelectedTo() === undefined) {
return 'Remove';
} else { return ''; }
});
}
After I click the add button, I am expecting PossessionChangesErrors to have one issue since it should load with undefined options. But I am getting nothing. Thanks again for helping!
EDIT:
Now I have the validation working, but I am not able to clear the validation to create a new row once one of the drop downs have been selected. Here is the fiddle: https://jsfiddle.net/p6x1nqm5/18/
Turns out I just didn't have the correct logic for the validation. Here is the new fiddle with the changes. https://jsfiddle.net/zw80kh2n/2/
self.IsValidRow became
self.IsValidRow = ko.pureComputed(function() {
return (!(self.SelectedFrom() === undefined && self.SelectedTo() === undefined))
}).extend({ bothUndefined: {}
});
and the validation became
ko.validation.rules['bothUndefined'] = {
getValue: function (o) {
return (typeof o === 'function' ? o() : o);
},
validator: function (val) {
return val;
},
message: 'Please select one change.'
};
ko.validation.registerExtenders();

How can we determine the group which initiated SignalR extended method?

I have created a Javascript function to make SignalR even more magical:
//Initializable
function Initializable(params) {
this.initialize = function (key, def, private) {
if (def !== undefined) {
(!!private ? params : this)[key] = (params[key] !== undefined) ? params[key] : def;
}
};
}
/*SignalR Updater*/
function SignalRUpdater(params) {
Initializable.call(this, params);
var self = this;
this.initialize("RawHubs", [], true);
this.initialize("RawGroups", {}, true);
this.initialize("Connection", $.connection, true);
this.initialize("Extend", {});
this.Hubs = {};
this.addHub = function (name, extend) {
if (self.Hubs[name]) {
return false;
}
self.Hubs[name] = params.Connection[name];
self.Hubs[name].Groups = {};
params.RawHubs.push(name);
if (!params.RawGroups[name]) {
params.RawGroups[name] = [];
}
if (extend) {
if ((!self.Extend) || (!extend.append)) {
self.Extend = extend;
} else {
if (!self.Extend) {
self.Extend = {};
}
if (extend.append) {
for (var extendIndex in extend) {
if (extendIndex !== "append") {
self.Extend = extend[extendIndex];
}
}
} else {
self.Extend = extend;
}
}
$.extend(params.Connection[name].client, self.Extend);
} else if (self.Extend) {
$.extend(params.Connection[name].client, self.Extend);
}
return true;
};
this.removeHub = function (name) {
if (!self.Hubs[name]) {
return false;
}
for (var groupIndex in self.Hubs[name].Groups) {
self.Hubs[name].Groups[groupIndex].unsubscribe();
}
delete self.Hubs[name];
delete params.RawGroups[name];
params.RawHubs.splice(params.RawHubs.indexOf(name), 1);
return true;
};
this.addGroupToHub = function (hubName, groupName) {
if ((self.Hubs[hubName]) && (self.Hubs[hubName].Groups[groupName])) {
return false;
}
self.Hubs[hubName].server.subscribe(groupName);
self.Hubs[hubName].Groups[groupName] = {}; //Here we can hold group-related data
if (params.RawGroups[hubName].indexOf(groupName) < 0) {
params.RawGroups[hubName].push(groupName);
}
return true;
};
this.removeGroupFromHub = function (hubName, groupName) {
if ((!self.Hubs[hubName]) || (!self.Hubs[hubName].Groups[groupName])) {
return false;
}
self.Hubs[hubName].server.unsubscribe(groupName);
delete self.Hubs[hubName].Groups[groupName];
if (params.RawGroups[hubName].indexOf(groupName) >= 0) {
params.RawGroups[hubName].splice(params.RawGroups[hubName].indexOf(groupName), 1);
}
return true;
};
for (var hubIndex in params.RawHubs) {
self.addHub(params.RawHubs[hubIndex]);
}
params.Connection.hub.start().done(function () {
for (var hubIndex in params.RawGroups) {
for (var groupIndex in params.RawGroups[hubIndex]) {
self.addGroupToHub(hubIndex, params.RawGroups[hubIndex][groupIndex]);
}
}
});
}
I am using it like this, for example:
function statusUpdate(status) {
alert(status);
}
var signalRUpdater = new SignalRUpdater({
RawHubs: ["statusUpdates"],
Extend: {
statusUpdate: statusUpdate
}
});
So far, so good. However, I may have several groups in the same hub and at the point of statusUpdate I do not seem to know about the group. I can send it from server-side as a parameter to statusUpdate, but I wonder whether this is an overkill and whether it is possible out of the box with SignalR.
When sending a group message to clients the server does not send the name of the group the message was sent to. The server selects clients that are members of the group and just sends them the message. If you want to understand the protocol SignalR is using you can find a description I wrote some time ago here.

Check if a string is in a json object

I'm trying to check if a string is in a JSON object with javascript. I don't know if it is possible or I have to convert something. Here is the part of the code with the if statement in which I want to check if data.userName (the string) is in users (the JSON object)
function validation() {
var userName_login = document.getElementById("username").value;
var password_login = document.getElementById("password").value;
var data = {
userName: userName_login,
password: password_login
};
doJSONRequest("GET", "/users/", null, data, function(users) {
if (data.userName) {
}
})
}
And the doJSONRequest function is:
function doJSONRequest(method, url, headers, data, callback) {
if (arguments.length != 5) {
throw new Error('Illegal argument count');
}
doRequestChecks(method, true, data);
var r = new XMLHttpRequest();
r.open(method, url, true);
doRequestSetHeaders(r, method, headers);
r.onreadystatechange = function() {
if (r.readyState != 4 || (r.status != 200 && r.status != 201 && r.status != 204)) {
return;
} else {
if (isJSON(r.responseText))
callback(JSON.parse(r.responseText));
else
callback();
}
};
var dataToSend = null;
if (!("undefined" == typeof data) && !(data === null))
dataToSend = JSON.stringify(data);
r.send(dataToSend);
}
function checkForValue(json, value) {
for (key in json) {
if (typeof (json[key]) === "object") {
return checkForValue(json[key], value);
} else if (json[key] === value) {
return true;
}
}
return false;
}
check if Json string has value in JS
Just try to parse it using JSON.parse, if the parse was successful return true else return false:
function isJSON(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}

Knockotjs Validation. Passing function gives undefined, because of property order inside VM

validation works fine if validation properties are placed after "HasError" property in VM.
In the case that the property placed before HasError I will get "parameters.hasError" as undefined. I think it's because the property "HasError" is not defined to that time.
Is there any solution without changing the order of the properties inside VM to make it work.
Thanks!
self._BusTypeDefault = function(param) {
var ret = param.BusType;
if(typeof(ret)==='undefined') {
ret = '';
}
else if(ko.isObservable(ret)) {
ret = ret.peek();
}
return ret;
};
self.BusType = ko.observable(self._BusTypeDefault(init)).extend({maxLength: {message: $Resources.PCIBUSError(), maxFieldLength: 255,hasError: self.HasError }});
self._HasErrorDefault = function(param) {
var ret = param.HasError;
if(typeof(ret)==='undefined') {
ret = false;
}
else if(ko.isObservable(ret)) {
ret = ret.peek();
}
return ret;
};
self.HasError = ko.observable(self._HasErrorDefault(init)).extend({errorAggregation: {}});
ko.extenders.maxLength = function (target, parameters) {
//add some sub-observables to our observable
target.hasMaxLengthError = ko.observable();
target.validationMessageMaxError = ko.observable();
//define a function to do validation
function validate(newValue) {
var preValue = target.hasMaxLengthError();
if (newValue.length >= parameters.maxFieldLength) {
target.hasMaxLengthError(true);
target.validationMessageMaxError(parameters.message || "This field is required");
}
else {
target.hasMaxLengthError(false);
target.validationMessageMaxError("");
}
if (parameters.hasError != null && target.hasMaxLengthError() !== preValue && typeof preValue !== 'undefined') {
parameters.hasError(target.hasMaxLengthError());
}
}
//initial validation
validate(target());
//validate whenever the value changes
target.subscribe(validate);
//return the original observable
return target;
};
You can use a function to delay the interpretation of hasError:
this.myObservable = ko.observable(1).extend({ myExtender : { hasError: function () { return self.hasError } } });
Then in the extender you'll need to call the function to actually get the observable behind:
ko.extenders.myExtender = function (target, params) {
function validate(newValue) {
alert("New Value: " + newValue + " ; Has Error: " + params.hasError()());
}
target.subscribe(validate);
}
See this example: http://jsfiddle.net/7ywLN/

Categories