Autodesk Forge Viewer API not working in React Native - react-native

A few days ago, I was trying to build Autodesk forge viewer API with react native by following this example:
https://forge.autodesk.com/blog/forge-react-native-au-talk
It works well. It used viewer v2.17, I up to viewer v7 but unfortunately, It doesn't show anything. I caught an error: Cannot read property 'texture' of null, when I use line viewer.start();
Please, help

Looking at your code it seems to me you're not using the viewer options properly on initializing.
The way to define the access token is by a callback as per the sample posted by Bryan.
Using the code below the viewer loaded in fine.
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<link rel="stylesheet" href="https://developer.api.autodesk.com/derivativeservice/v2/viewers/style.min.css?v=v7.*" type="text/css">
<script src="https://developer.api.autodesk.com/derivativeservice/v2/viewers/three.min.js?v=v2.17"></script>
<script src="https://developer.api.autodesk.com/derivativeservice/v2/viewers/viewer3D.js?v=v7.*"></script>
</head>
<body style="margin:0">
<div id="viewer"></div>
</body>
<script>
var viewer = null;
function initializeViewer(urn, token) {
var options = {
env: "AutodeskProduction",
getAccessToken: function(onTokenReady) {
var token = 'access token provided by 2 legged api';
var timeInSeconds = 3600; // Use value provided by Forge Authentication (OAuth) API
onTokenReady(token, timeInSeconds);
}
}
Autodesk.Viewing.Initializer(options, () => {
try {
viewer = new Autodesk.Viewing.GuiViewer3D(document.getElementById('viewer'));
viewer.start();
console.log('viewer loaded');
} catch (err) {
alert(err)
}
});
function onDocumentLoadSuccess(doc) {
var viewables = doc.getRoot().getDefaultGeometry();
viewer.loadDocumentNode(doc, viewables).then(i => {
// documented loaded, any action?
});
}
function onDocumentLoadFailure(viewerErrorCode) {
console.error('onDocumentLoadFailure() - errorCode:' + viewerErrorCode);
}
}
</script>

Related

Show custom error message on passwordless Auth0 page

I would like to only allow certain phone numbers when patients sign up to my application through a passwordless Auth0 page.
For this I added a custom Auth0 action to the Pre User Registration flow.
My custom action checks the phone prefix:
/**
* Handler that will be called during the execution of a PreUserRegistration flow.
*
* #param {Event} event - Details about the context and user that is attempting to register.
* #param {PreUserRegistrationAPI} api - Interface whose methods can be used to change the behavior of the signup.
*/
exports.onExecutePreUserRegistration = async (event, api) => {
if (!isAllowedPhoneNumber(event.user.phone_number)) {
api.access.deny('my_custom_identifier', 'My Custom Message');
}
};
const allowedPhonePrefixes = ["+43", "+32", "+420", "+45"];
const isAllowedPhoneNumber = (phoneNumber) =>
allowedPhonePrefixes.some((prefix) => phoneNumber.startsWith(prefix));
However, "My Custom Message" doesn't show up when I try a phone number outside those allowed. Instead, I see the default "We're sorry, something went wrong".
I then tried to edit the HTML code of my custom Auth0 login page adding this:
languageDictionary = {
...languageDictionary,
passwordless: {
"lock.fallback": "My Custom Message",
"no_signups_from_outside_schengen_area": "My Custom Message 2",
}
};
So the HTML code of my page now looks like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Sign In with Auth0</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<!--[if IE 8]>
<script src="//cdnjs.cloudflare.com/ajax/libs/ie8/0.2.5/ie8.js"></script>
<![endif]-->
<!--[if lte IE 9]>
<script src="https://cdn.auth0.com/js/base64.js"></script>
<script src="https://cdn.auth0.com/js/es5-shim.min.js"></script>
<![endif]-->
<script src="https://cdn.auth0.com/js/lock/11.30/lock.min.js"></script>
<script>
// Decode utf8 characters properly
var config = JSON.parse(decodeURIComponent(escape(window.atob('##config##'))));
config.extraParams = config.extraParams || {};
var connection = config.connection;
var prompt = config.prompt;
var languageDictionary;
var language;
if (config.dict && config.dict.signin && config.dict.signin.title) {
languageDictionary = { title: config.dict.signin.title };
} else if (typeof config.dict === 'string') {
language = config.dict;
}
var loginHint = config.extraParams.login_hint;
languageDictionary = {
...languageDictionary,
passwordless: {
"lock.fallback": "My Custom Message",
"no_signups_from_outside_schengen_area": "My Custom Message 2",
}
};
var lock = new Auth0LockPasswordless(config.clientID, config.auth0Domain, {
auth: {
redirectUrl: config.callbackURL,
responseType: (config.internalOptions || {}).response_type ||
(config.callbackOnLocationHash ? 'token' : 'code'),
params: config.internalOptions
},
configurationBaseUrl: config.clientConfigurationBaseUrl,
overrides: {
__tenant: config.auth0Tenant,
__token_issuer: config.authorizationServer.issuer
},
assetsUrl: config.assetsUrl,
allowedConnections: connection ? [connection] : null,
rememberLastLogin: !prompt,
language: language,
languageBaseUrl: config.languageBaseUrl,
languageDictionary: languageDictionary,
theme: {
logo: 'https://link-to-my-logo.something',
primaryColor: '#429db3'
},
closable: false,
showTerms: false
});
lock.show();
</script>
</body>
</html>
... but still neither "My Custom Message" nor "My Custom Message 2" show up. I still see "We're sorry, something went wrong".
How can I show a custom error message to users who enter a phone number from outside the list of allowed countries?
Note: I am pretty sure that the custom Auth0 action works, as I am able to prevent sign-ups for certain phone prefixes. What is probably wrong is the way I'm changing the code of the HTML page shown above, I suppose.
There is a partial solution that allows to show a custom message for all extensibility errors. (I haven't found a way to show different custom messages for different extensibility errors.)
This partial solution involves changing the structure in which the languageDictorionary variable above is structured:
languageDictionary = {
...languageDictionary,
error: {
passwordless: {
extensibility_error: "My Custom Message for all extensibility errors"
}
}
};
This way, any call to api.access.deny in the Pre User Registration flow will show "My Custom Message for all extensibility errors", no matter what identifier or message is passed to api.access.deny.

What is the meaning of local speech synthesizer in TTS APIs

I have tried all the methods and routines on the stackoverflow so far to get the TTS working for voice values with lang: "hi-IN", name: "Google हिन्दी" voiceURI: "Google हिन्दी" but no luck so far.
The one thing I observed in list of 21 languages shown in array of getVoices()
Microsoft David Desktop - English (United States) and
Microsoft Zira Desktop - English (United States)
has local service property set to true. and David's default value is true. Rest all 19 entries have both values set as false. Is this the reason for not getting it required language (Hindi) voice. Is there any additional setting or plug in required? Any help will is highly appreciated.
I think, I got the issue. The windows system should have required language along with speech installed. Otherwise it will not work. I am facing some issue with installing language from settings but will update once done and tested successfully.
Here's a basic example:
// Load voices
let voices = [];
if (speechSynthesis.onvoiceschanged !== undefined) {
speechSynthesis.onvoiceschanged = () => {
voices = speechSynthesis.getVoices()
};
}
voices = speechSynthesis.getVoices();
// Function to build and speak utterance
const speak = () => {
const msg = new SpeechSynthesisUtterance('1, 2, 3');
msg.voice = voices.find(v => v.lang === 'hi-IN');
msg.lang = 'hi-IN';
msg.onerror = (e) => {console.log('Error', e)};
speechSynthesis.cancel();
speechSynthesis.speak(msg);
}
// Speak upon clicking button
document.addEventListener('DOMContentLoaded', () => {
document.querySelector('#speak').addEventListener('click', () => {
speak();
});
});
<!DOCTYPE html>
<html>
<head>
<title>57990014</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="57990014.js"></script>
</head>
<body>
<div>
<button type="button" id="speak">Speak</button>
</div>
</body>
</html>
Does it speak in English? Try with this revised speak function:
const speak = () => {
const msg = new SpeechSynthesisUtterance('1, 2, 3');
msg.onerror = (e) => {console.log('Error', e)};
speechSynthesis.cancel();
speechSynthesis.speak(msg);
}

Styles and events not working in marko template

My component is loading fine but the styles are not loading, nor are the events firing. I am following the documentation and no errors are being thrown but it seems I might be missing something fundamental here?
View template rendered with res.marko:
import Explanation from "./components/explanation.marko";
<!DOCTYPE html>
<html lang="en">
<head>
...
</head>
<body>
...
<include(Explanation, input.explanation) />
...
</body>
</html>
explanation.marko file:
class {
onExplanationClick() {
console.log("Explanation clicked");
}
}
style {
.explanation-paragraph {
color: red;
}
}
<div id="explanation" on-click('onExplanationClick')>
<for (paragraph in input.content)>
<p class="explanation-paragraph">${paragraph}</p>
</for>
</div>
Server side:
app.get("/explanation/:id", async function(req, res) {
var explanation = await findExplanation(req.params.id);
var template = require("../../views/explanation/explanation.marko");
res.marko(template, { explanation, user: req.user });
});
Also using marko/node-require and marko/express.
You will need to integrate a module bundler/asset pipeline. In the sample marko-express app we are using Lasso (an asset pipeline + JavaScript module bundler).
There's also another sample app that integrates Webpack: https://github.com/marko-js-samples/marko-webpack
The Marko team supports both Lasso and Webpack, but we recommend Lasso because it is simpler and requires minimal configuration.
Please take a look at the marko-express app and feel free to ask questions in our Gitter chat room if you get stuck: https://gitter.im/marko-js/marko

Google Plus Signin 'Unknown RPC service: widget-interactive-I0_1370237493291'

Sorry for such a noob question.
I just followed following google plus signin's Step1 to Step4.
https://developers.google.com/+/web/signin/
The signin seemed to succeed, while an error 'Unknown RPC service: widget-interactive-I0_1370237493291' emerged. Here are the console logs on Chrome.
XHR finished loading: "https://plusone.google.com/_/scs/apps-static/_/js/k=oz.connect.en_US.B31L_d…sv=1/d=1/ed=1/am=GA/rs=AItRSTOhxGvE7YZFbwjOy6nLkxCnNjz3og/cb=gapi.loaded_1". signin:15
XHR finished loading: "https://plusone.google.com/_/scs/apps-static/_/js/k=oz.gapi.en.hgKKOofQjvI.…sv=1/d=1/ed=1/am=EQ/rs=AItRSTOeNwU4i5ApX9gPGjnZ0AzovKWmWw/cb=gapi.loaded_0". signin:15
Unknown RPC service: widget-interactive-I0_1370237493291 cb=gapi.loaded_0:71
signed in
I think the error is about something incomplete. I cannot figure out what the exactly the error is and how to get it clear. What am I missing?
Here is the code. The origin is http://localhost:3000
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Gplus</title>
</head>
<body>
<h1>Gplus</h1>
<span id="signinButton">
<span
class="g-signin"
data-callback="signinCallback"
data-clientid="362449793624.apps.googleusercontent.com"
data-cookiepolicy="single_host_origin"
data-requestvisibleactions="http://schemas.google.com/AddActivity"
data-scope="https://www.googleapis.com/auth/plus.login">
</span>
</span>
<script type="text/javascript">
function signinCallback(authResult) {
if (authResult['access_token']) {
// Successfully authorized
// Hide the sign-in button now that the user is authorized, for example:
document.getElementById('signinButton').setAttribute('style', 'display: none');
console.log('signed in');
} else if (authResult['error']) {
// There was an error.
// Possible error codes:
// "access_denied" - User denied access to your app
// "immediate_failed" - Could not automatically log in the user
// console.log('There was an error: ' + authResult['error']);
}
}
</script>
<!-- Place this asynchronous JavaScript just before your </body> tag -->
<script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/client:plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script>
</body>
</html>
I had the same problem when I was trying that code sample. When trying to figure it out, I found this post:
https://groups.google.com/forum/?fromgroups#!topic/google-plus-developers/Ax3cMLhMR4Q
in the Google+ Developers Forum that seems to indicate that it's not really an 'error' but some kind of warning. If I find out more, I'll post an update here.
Hope this helps.

Coding with Dojo, received error 'dijit.byId(...)' is null or not an object

I see many references to this error on the web, but they are not helping me. I guess i am new enough to this that i need a specific answer for my problem.
I am attaching the first portion of code on a page that i am running. the last line i show is the line that is creating the error stating in the title. Please let me know if you have any suggestions.
Thank you!
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>CDI Web Portal</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<script src="js\dojo\dojo.js" type="text/javascript"></script>
<script type="text/javascript" src="http://www.google.com/jsapi?key=ABQIAAAA5a4NhilcmrdMQ5e3o22QWRQWrGbhbxAguaJ-a4SLWYiya7Z2NRTDfQBdxmHdf5ydkZYLZTiz1tDXfg"></script>
<script type="text/javascript" src="ge-poly-fit-hack.js"></script>
<script type="text/javascript" src="kmldomwalk.js"></script>
<style type="text/css">
#import "js/dijit/themes/tundra/tundra.css";
#import "js/dojo/resources/dojo.css";
</style>
<style type="text/css">#import "index.css";</style>
<script type="text/javascript"> dojo.ready(function() { dojo.byId("greeting").innerHTML += ", from " + dojo.version; }); </script>
<script type="text/javascript">
// <![CDATA[
djConfig = { parseOnLoad: true };
// google.load("dojo", "1.6.1");
google.load("maps", "2");
google.load("earth", "1");
var g_ge;
var g_earthDisabled = false;
var g_kmlObject;
google.setOnLoadCallback(function() {
dojo.require('dijit.layout.BorderContainer');
dojo.require('dijit.layout.SplitContainer');
dojo.require('dijit.layout.ContentPane');
dojo.require('dijit.Tree');
//dojo.require('CheckboxTree');
dojo.require('dijit.form.CheckBox');
dojo.require('dijit.form.Button');
dojo.require('dijit.form.TextBox');
dojo.require('dojo.data.ItemFileWriteStore');
dojo.require('dojo.parser');
dojo.require('dojo.cookie');
dojo.require('dojo.fx');
dojo.addOnLoad(function() {
// load checkboxtree
var scpt = document.createElement('script');
scpt.src = "dijit.CheckboxTree.js";
document.body.appendChild(scpt);
{ dijit.byId('load-button').setDisabled(true) };
// build earth
google.earth.createInstance(
'map3d',
function(ge) {
g_ge = ge;
g_ge.getWindow().setVisibility(true);
g_ge.getNavigationControl().setVisibility(ge.VISIBILITY_AUTO);
g_ge.getLayerRoot().enableLayerById(g_ge.LAYER_BORDERS, true);
g_ge.getLayerRoot().enableLayerById(g_ge.LAYER_BUILDINGS, true);
dijit.byId('load-button').setDisabled(false);
checkAutoload();
},
function() {
g_earthDisabled = true;
dijit.byId('load-button').setDisabled(true);
From your comment, you used declarative syntax to create the dijit, i.e. <button id="load-button" dojoType="dijit.form.Button" onclick="loadKml();">. If the declarative syntax is used, the dijit is actually created after the page is loaded. So you should put the code to use the dijit in the Dojo's load callback, i.e. inside of dojo.addOnLoad callback.
But your code is bad formatted and mingled with Google Maps load callback, it's not easy to inspect the code. My suggestion would be to wrap the dijit.byId('load-button').setDisabled(true); with dojo.addOnLoad, like below:
dojo.addOnLoad(function() {
dijit.byId('load-button').setDisabled(true);
});
It means that you've got a dojo object rather than a dijit object -- or possibly no object named load-button at all, since it's not clear from this where load-button is being created. Make sure there is an object with id="load-button" that was created with dijit.