Office.context.roamingSettings.saveAsync function gives a error when using Dialog API for Office Add-in - outlook-addin

i get following error when saving roaming setting value.this Office.initialize method is defined in a dialog box window(myDialog.html) and it is called using
Office.context.ui.displayDialogAsync('https://myAddinDomain/myDialog.html');
Office.initialize = function (reason) {
$(document).ready(function () {
//console.log("Sending auth complete message through dialog: " + oauthResult.authStatus);
Office.context.roamingSettings.set("o365auth", 'yyryy');
Office.context.roamingSettings.saveAsync(function (asyncResult) {
if (asyncResult.status === "success") {
var dataValue = result.value; // Get selected data.
} else {
var err = result.error;
}
});
});
}
error says "
Uncaught TypeError: Cannot read property 'invoke' of null
at window.OSF.DDA.OutlookAppOm.u.DDA.OutlookAppOm.invokeHostMethod "

Currently, we only support the Office.context.ui.messageParent API inside the dialog.

Related

Vue VeeValidate - How to handle exception is custom validation

I have a custom validation in VeeValidate for EU Vat Numbers. It connects to our API, which routes it to the VIES webservice. This webservice is very unstable though, and a lot of errors occur, which results in a 500 response. Right now, I return false when an error has occured, but I was wondering if there was a way to warn the user that something went wrong instead of saying the value is invalid?
Validator.extend('vat', {
getMessage: field => 'The ' + field + ' is invalid.',
validate: async (value) => {
let countryCode = value.substr(0, 2)
let number = value.substr(2, value.length - 2)
try {
const {status, data} = await axios.post('/api/euvat', {countryCode: countryCode, vatNumber: number})
return status === 200 ? data.success : false
} catch (e) {
return false
}
},
}, {immediate: false})
EDIT: Changed code with try-catch.
You can use:
try {
your logic
}
catch(error) {
warn user if API brokes (and maybe inform them to try again)
}
finally {
this is optional (you can for example turn of your loader here)
}
In your case try catch finally block would go into validate method
OK, first of all I don't think that informing user about broken API in a form validation error message is a good idea :-| (I'd use snackbar or something like that ;) )
any way, maybe this will help you out:
I imagine you are extending your form validation in created hook so maybe getting message conditionaly to variable would work. Try this:
created() {
+ let errorOccured = false;
Validator.extend('vat', {
- getMessage: field => 'The ' + field + ' is invalid.',
+ getMessage: field => errorOccured ? `Trouble with API` : `The ${field} is invalid.`,
validate: async (value) => {
let countryCode = value.substr(0, 2)
let number = value.substr(2, value.length - 2)
const {status, data} = await axios.post('/api/euvat', {countryCode: countryCode, vatNumber: number})
+ errorOccured = status !== 200;
return status === 200 ? data.success : false;
},
}, {immediate: false})
}
After searching a lot, I found the best approach to do this. You just have to return an object instead of a boolean with these values:
{
valid: false,
data: { message: 'Some error occured.' }
}
It will override the default message. If you want to return an object with the default message, you can just set the data value to undefined.
Here is a veeValidate v3 version for this:
import { extend } from 'vee-validate';
extend('vat', async function(value) {
const {status, data} = await axios.post('/api/validate-vat', {vat: value})
if (status === 200 && data.valid) {
return true;
}
return 'The {_field_} field must be a valid vat number';
});
This assumes your API Endpoint is returning json: { valid: true } or { valid: false }

Vuejs. I can't transfer data to an Object

I would like to catch uploaded file in FilePond. but the base64 of the file isn't transfered to my object. Any solutions?
In template
<FilePond
v-on:addfile="catch"
/>
In Data
data:function() {
return {
image:'',
}}
in Method
catch: function(fieldName, file) {
console.log('#', file.file) // The Blop format file appears in console
const reader = new FileReader(); //convert to base64
reader.readAsDataURL(file.file);
reader.onloadend = function() {
console.log('yy',reader.result); // Base64 image appears in console
(600000 carac)
this.image= reader.result ; // HERE, the object still blank
} },
Error in console :
Uncaught TypeError: Cannot set property 'image' of undefined
at FileReader.reader.onloadend
this keyword is shadowed by the onloadend function, save this before defining the function and then reference it inside:
methods: {
catch: function(fieldName, file) {
// ...
var ref = this
reader.onloadend = function() {
ref.image= reader.result // use ref here
}
// ...
}
}

dojo on.js TypeError matchesTarget is undefined

I'm working to extend some legacy dojo code (v1.8). I added a button which when clicked calls a simple handle function. The problem is, nothing happens when I click the button and I get the following error in Firebug:
TypeError: matchesTarget is undefined
Everthing worked before, and I only added the following code:
require(["dojo/on"], function (on) {
on(document.getElementById("submitBtn"), "button:click", function (e) {
onSubmitQuery();
});
});
onSubmitQuery:function () {
var model_type_uuid = document.getElementById("modelTypeSelect").get('value');
// check to see if model_type_uuid is not undefined before submitting
if (model_type_uuid === undefined || model_type_uuid == "00000000-0000-0000-0000-000000000000") {
alert('Invalid Decision Model Type ' + model_type_uuid + ' for Decision Query submission');
return;
}
if (document.getElementByID("modeSelector").get('value') == "simulate") {
submitStandingQuery(model_type_uuid);
} else {
submitInteractiveQuery(model_type_uuid);
}
}
I've been pulling my hair out trying to figure this out. Please help!
You need to add the dojo/query module in order to match the selector button within its parent node submitBtn.
require(["dojo/on", "dojo/query"], function (on) {
on(document.getElementById("submitBtn"), "button:click", function (e) {
onSubmitQuery();
});
});

Uncaught TypeError: Object #<Object> has no method 'navigateTo'?

I created a project using hottowel 2.0.1 in VS 2012 and have the following code following the HotTowel course/example. However I got following error.
Uncaught TypeError: Object # has no method 'navigateTo' ?
I set a break point at the line and found router doesn't have method navigateTo. However, it does have method navigate. Is the name changed?
define(['services/datacontext', 'plugins/router', 'services/logger'],
function (datacontext, router, logger) {
......
var gotoDetails = function (selectedEvent) {
if (selectedEvent && selectedEvent.Id()) {
var url = '#/eventdetail/' + selectedEvent.Id();
router.navigateTo(url);
}
};
var viewAttached = function (view) {
bindEventToList(view, '.event-brief', gotoDetails);
};
var bindEventToList = function (rootSelector, selector, callback, eventName) {
var eName = eventName || 'click';
$(rootSelector).on(eName, selector, function () {
var event = ko.dataFor(this);
callback(event);
return false;
});
};
//#endregion
var vm = {
activate: activate,
deactivate: deactivate,
refresh: refresh,
events: events,
title: title,
attached: viewAttached
};
return vm;
});
You should convert your application to Durandal 2:
http://www.johnpapa.net/upgrading-durandal-to-version-2-0/
(amongst other changes there is this: router.navigateTo is now router.navigate)
or use official Durandal 2 template instead of HotTowel

Returning value from file read with WinJS for use in page

I currently have an issue with a file read in a Windows 8/WinRT application. I have a simple navigation style app, several pages have access to the same data and I have a data.js file that defines a namespace (Data) with a number of members. One part of the application saves items to a txt file stored in the applications local data folder. But on some of the other pages I need to read this in or check for the existence of an item within the list of previously saved items. To do this I added another method into the data.js file. The trouble is, when I call this method to check for the existence of an item, it doesn't return the value straight away due to the async nature, but the rest of code in the page specific js file still seems to execute before it jumps back into the parsing. This means that the logic to check for an item doesn't seem to work. I have a feeling it's down to my use of either .done or .then but my code is as follows:
DATA.JS
var doesItemExist= function(item_id){
var appFolder = Windows.Storage.ApplicationData.current.localFolder;
//note I've tried this with and without the first "return" statement
return appFolder.getFileAsync(dataFile).then(function (file) {
Windows.Storage.FileIO.readTextAsync(file).done(function (text) {
try {
var json = JSON.parse(text);
if (json) {
for (var i = 0; i < json.items.length; i++) {
var temp_item = json.items[i];
if (temp_item.id === item_id) {
return true;
break;
}
}
} else {
return false;
}
} catch (e) {
return false;
console.log(e);
}
}, function (e) { return false;console.log(e); });
}, function (e) { // error handling
return false;
console.log(e);
});
}
WinJS.Namespace.define("Data", {
doesItemExist: doesItemExist
}); //all of the above is wrapped in a self executing function
Then on Page.js I have the following:
var add = document.getElementById('add');
if (Data.doesItemExist(selected_item.id)) {
add.style.display = 'block';
} else {
add.style.display = 'none';
}
All the variables here are assigned and debugging doesn't produce any errors, control just appears to go back to the if/else statement after it hits the getFileAsync but before it even goes through the for loop. But subsequently it does go in to the for loop but after the if statement has finished. I'm guessing this is down to the async nature of it all, but I'm not sure how to get around it. Any ideas?
thanks
A Promise should work here.
I created a new Navigation app, and added a Data.js file containing the following code:
(function () {
var appData = Windows.Storage.ApplicationData;
function doesItemExist(item_id) {
return new WinJS.Promise(
function (completed, error, progress) {
var exists = false;
appData.current.localFolder.createFileAsync("data.txt", Windows.Storage.CreationCollisionOption.openIfExists).then(
function (file) {
Windows.Storage.FileIO.readTextAsync(file).then(
function (fileContents) {
if (fileContents) {
if (fileContents = "foo!") {
completed(true);
}
else {
completed(false);
}
}
else {
completed(false);
}
}
);
},
function (e) {
error(e);
}
);
}
);
}
WinJS.Namespace.define("Data", {
doesItemExist: doesItemExist
});
})();
Note that I've simplified the code for retrieving and parsing the file, since that's not really relevant to the problem. The important part is that once you've determined whether the item exists, you call completed(exists) which triggers the .then or .done of the Promise you're returning. Note that you'd call error(e) if an exception occurs, as I'm doing if there's an exception from the call to createFileAsync (I use this call rather than getFileAsync when I want to be able to either create a file if it does not exist, or return the existing file if it does, using the openIfExists option).
Then, in Home.js, I added the following code to the ready handler:
var itemExists;
var itemExistsPromise = Data.doesItemExist(42);
itemExistsPromise = itemExistsPromise.then(function (exists) {
itemExists = exists;
var content = document.getElementById("content");
content.innerText = "ItemExists is " + itemExists;
});
itemExistsPromise.done(function () {
var a = 42;
});
var b = 0;
The code above sets the variable itemExistsPromise to the returned promise from the function in Data.js, and then uses an anonymous function in the .then function of the Promise to set the variable itemExists to the Boolean value returned from the doesItemExist Promise, and grabs the <p> tag from Home.html (I added an id so I could get to it from code) and sets its text to indicate whether the item exists or not). Because I'm calling .then rather than .done, the call returns another promise, which is passed into the itemExistsPromise variable.
Next, I call itemExistsPromise.done to do any work that has to wait until after the work performed in the .then above it.
If you set a breakpoint on the lines "var a = 42" and "var b = 0" (only included for the purpose of setting breakpoints) as well as on the line "itemExists = exists", you should find that this gives you the control you need over when the various parts are executed.
Hope that helps!