can't compile react app with forge viewer - can't compile - Autodesk not defined un-def - autodesk-forge

we want to move some of our forge viewer code base into a react-app and can't figure out how to use the viewer3d js api without appending all Autodesk.Viewer.... usages in our components with window.* This works in all the (excellent and extensive) git samples we've studied. why? we load the viewer3d.js file in the index.html between the and the react landing :
<body>
<script src="https://developer.api.autodesk.com/derivativeservice/v2/viewers/viewer3D.js?v=6.0" />
<div id="root" />
the error we get (for every instance of usage of the Autodesk namespace):
Failed to compile
./src/components/Viewer.js
Line **: 'Autodesk' is not defined no-undef
this works:
this.viewer = new window.Autodesk.Viewing.Private.GuiViewer3D(this.viewerContainer)
this doesn't work:
this.viewer = new Autodesk.Viewing.Private.GuiViewer3D(this.viewerContainer)

As mentioned in this user guide, you need to explicitly read any global variables from window. Put this at the top of the file and it will work:
const Autodesk = window.Autodesk;
And it's recommended to yank your script tag to the header section of your app's entry html to make sure it gets loaded prior to the React emits:
<!DOCTYPE html>
<html lang="en">
<head>
...
<script src="https://developer.api.autodesk.com/derivativeservice/v2/viewers/viewer3D.js?v=6.0" />
</head>
...

we resolved this by putting a global in the first row of our component files.
based on this.
/*global Autodesk*/
but, i do like this one even better, right behind the imports. thank you, Bryan.
const Autodesk = window.Autodesk;

I have prepared a autodesk-forge-viewer typing module, you can use it to verify types during compilation.
It is used this way:
import Autodesk from 'autodesk-forge-viewer';
const autodesk: typeof Autodesk = (window as any).Autodesk;
For some limitations of type latest TypeScript the type will be Autodesk and the value will be autodesk, so here is the code to create a Viewer instance:
const viewer: Autodesk.Viewing.Private.GuiViewer3D = new autodesk.Viewing.Private.GuiViewer3D(viewerContainer);
Please take a note that autodesk-forge-viewer module doesn't include Viewer implementation, so you still must add viewer3D.js script to the index.html.

Related

Google sheets: Class google.script.run not working

My problem is simple. All the possible solutions I searched for online did not address my question.
Google's developer website for Class google.script.run (https://developers.google.com/apps-script/guides/html/reference/run#withSuccessHandler) showcased the method myFunction(...) (any server-side function).
I have copied their exact code and html code and deduced that the function doSomething() does not execute. Nothing gets logged.
I intend to use this to execute an HTML file so that I could play a sound file. I could do this so far with a sidebar popping up from the side, as discussed in this thread: Google Script: Play Sound when a specific cell change the Value.
However, this code provided by Google does not work. Why?
function doGet() {
return HtmlService.createHtmlOutputFromFile('Index');
}
function doSomething() {
Logger.log('I was called!');
}
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
google.script.run.doSomething();
</script>
</head>
<body>
</body>
</html>
By using google.script.run you are calling a server-side Apps Script function.
https://developers.google.com/apps-script/guides/html/reference/run
Please double-check that you follow the following steps to do it correctly:
Please make sure that you put the html part of the code in a separate HTML file (which you create through File->New->HTML file) with the name corresponding to the one you are calling in HtmlService.createHtmlOutputFromFile() - in your case Index.html
Select “doGet” as the function to be run.
Deploy the script as a web app - this is the requirement for using Apps Script HTML service. Please find the instructions here: https://developers.google.com/apps-script/guides/web
Make sure that every time after you implement changes in your code, you deploy the script as a NEW project version. This is necessary to update the changes.
Open the current web app URL you obtain after updating your version, to open your html output.
In your case only an empty HTML file will be opened, to test functionality - insert some text in your HTML body, to test the correct functionality. The latter can be confirmed by viewing the Logs after running the code.

Polymer breaks with old version of Mootools

Latest Update (also updated post title)
So I tracked down the issue to the old version of Mootools (which I cannot upgrade or remove due to project restrictions).
Mootools does the following, which is the code that causes the issue:
/*
Class: Abstract
Abstract class, to be used as singleton. Will add .extend to any object
Arguments:
an object
Returns:
the object with an .extend property, equivalent to <$extend>.
*/
var Abstract = function(obj){
obj = obj || {};
obj.extend = $extend;
return obj;
};
//window, document
var Window = new Abstract(window);
var Document = new Abstract(document);
The new definitions of Window and Document is what's breaking Polymer imports. Any suggestions on updating the code above to gracefully extend the Document/Window objects without breaking existing functionality?
OLD description below before I discovered the issue lies with mootools
I've already included the webcomponents.js script.
Then, when I have the for polymer.html, the errors below start appearing, and my polymer components doesn't work.
The components works in isolation using the polymer-cli. Anyone know what may be causing this issue?
EDIT: So this is what I have in my <head>
<script src="/media/bower_components/webcomponentsjs/webcomponents.js"></script>
<link rel="import" href="/media/bower_components/polymer/polymer.html">
(...sorry I cannot show more, private company code and what-not)
That's literally all I need in my page to raise the error mentioned above.
I'm starting to think there is some other javascript library (there's a lot) that might be interfering with Polymer, since I cannot replicate the issue on a brand new site.
I should also note, there are no 404's. The polymer.html file does get loaded as expected in the browser, I verified this in my network panel in developer console.

Browser crashes on angularjs $http.get

I'm working on a template system with angularJs, and I am including template files to my view with ng-include from an external js-file.
When I run my index.html the browser, it crashes after a long while. It seems as if the page continues to reload over and over, and my CPU monitor goes through the roof.
What on Earth can be wrong? I am fairly new at angularjs, so if anyone could point me in the right direction, I'd be very thankful.
index.html
<!DOCTYPE html>
<html lang="en" data-ng-app="angularTemplate" data-ng-controller="templateCtrl">
<head>
<meta charset="UTF-8">
<title>{{ pageName + " - " + siteName }}</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
</head>
<body>
<header data-ng-include="includeHeader()"></header>
<script type="text/javascript" src="./assets/js/templateCtrl.js"></script>
</body>
</html>
JS
var app = angular.module('angularTemplate', []);
app.controller('templateCtrl', function($scope, $http) {
$scope.includeHeader = function(){
$http.get("./assets/php/mysql.php?action=getSiteSetup")
.success(function(response){
$scope.siteName = response.siteName;
$scope.siteTagline = response.siteTagline;
});
return "./assets/templates/header.html";
}
});
the mysql.php?action=getSiteSetup is a simple sql call which returns
{"siteName":"AngularJS Template","siteTagline":"Just another template...","siteBaseURL":"http:\/\/localhost\/angularjs_template\/"}
This issue exists because of the following two implementations:
<header data-ng-include="includeHeader()">
and
$scope.includeHeader = function(){
$http.get("./assets/php/mysql.php?action=getSiteSetup")
...
}
You need to understand how AngularJS's scope works to detect change in scope. See here
Basically AngularJS will repeatedly rerun the expression given and compare it to its previous value to determine if its value has changed, if it did, then it will do whatever it needs upon scope variable change. Therefore includeHeader() here is rerun repeatedly every time AngularJS wants to check if things have changed. However inside your includeHeader, it triggers a network call every time. To make things into an infinite loop, one of the triggers for AngularJS to decide if it needs to check for scope change is upon the completion of $http. There's your infinite loop.
In short, do not use any expression for scope value check if it's process intensive and vice versa. includeHeader is NOT where you should put initialization code. Simply trigger it in controller.
For routing between pages you should use Angular-Route or ui.router.
It is described here with examples: https://docs.angularjs.org/tutorial/step_07
This uses ng-view directive witch allows you to inject content based on called url from your web-app.
Here you have ng-view docs: https://docs.angularjs.org/api/ngRoute/directive/ngView
I really recomend you to read it and solve it this way. This completly remodel your work but will let you work easier and faster in future. And also it will make much easier making a tests to it.
Also please past your header.html code for improving this answer.
Remove the Ajax request from inside the function that data-ng-include directive binds to in the controller so that the code looks like the following
var app = angular.module('angularTemplate', []);
app.controller('templateCtrl', function($scope, $http) {
$http.get("./assets/php/mysql.php?action=getSiteSetup")
.success(function(response){
$scope.siteName = response.siteName;
$scope.siteTagline = response.siteTagline;
});
$scope.includeHeader = function(){
return "./assets/templates/header.html";
}
});
Note:
You don't necessary need to bind the ng-include directive to a
function on the scope when the template is not loaded dynamically
based on user interactions

F# FSharp.Literate formatted code snippet does not display correctly (.css & .js?)

I'm trying to use FSharp.Literate to produce html pages. I'm working in Xamarin using Mono 4.5. I want to turn basic *.fsx scripts into html. I am using the simple script example from the documentation for tests. The script I wish to turn into html looks like this.
(**
# First-level heading
Some more documentation using `Markdown`.
*)
(*** include: final-sample ***)
(**
## Second-level heading
With some more documentation
*)
(*** define: final-sample ***)
let helloWorld() = printfn "Hello world!"
I used the built in NuGet manager to download FSharp.Formatting. It also installed Microsoft.AspNet.Razor 2 and RazorEngine
Based on the example in the documentation, I wrote the following script to turn the above example into html. I'm using the html template from the original FSharp.Formatting on github.
#I "bin/Debug/"
#r "FSharp.Literate.dll"
#r "FSharp.Markdown.dll"
#r "FSharp.CodeFormat.dll"
open System.IO
open FSharp.Literate
let source = __SOURCE_DIRECTORY__
let baseDir = Path.Combine(source, "html/")
let file = Path.Combine(baseDir, "demo.fsx")
let output = Path.Combine(baseDir, "demo-script.html")
let template = Path.Combine(baseDir, "template.html")
Literate.ProcessScriptFile(file, template, output)
The process runs and it does produce an html file. However, the F# code does not tokenize. Instead of nicely formatted code, I get the example below. Am I missing something obvious?
Edit:
Based on Tomas' comment below, I found the problem with the .css and .js files.
The template I used had href="{root}/content/style.css" /> <script src="{root}/content/tips.js"
The {root} tag was the reason it could not find the css and js files.
Changing that to href="content/style.css" /> <script src="content/tips.js" solved the problem
I think the library actually produced the correct HTML. As you can see at the end of the file, the content that should appear in the tool tips (information about the type of helloWorld and printfn) is there.
The problem is likely that the generated HTML file does not correctly reference tips.js and style.css that defines the formatting for the HTML and script to pop-up the tool tips.
These two files should be included in the NuGet package (together with the default templates), or you can find them on the project GitHub.

google closure library usage from google app scripts using HtmlService

Is it possible to access google closure library functions from google app scripts via HtmlService? The html files in the google scripts seems to be filtering out anything related to closure library.
project: I am exploring DOM manipulation utilities from Google Closure library from within the google app scripts using HtmlService. I intend to run this as a stand alone web app.
The closure functions work when directly loaded into the browser from its local client environment - but they dont work when injected from GAS app via the HtmlService utility.
Here is the code I am using in the GAS.
html file
<html>
<head>
<script src="http://closure-library.googlecode.com/svn/trunk/closure/goog/base.js"></script>
<script>
goog.require('goog.dom');
function c_sayHi() {
var newHeader = goog.dom.createDom('h1', {'style': 'background-color:#EEE'},'Hello world!');
goog.dom.appendChild(document.body, newHeader);
}
</script>
</head>
<script>
function c_updateButton(date, button) {
button.value = "clicked at " + date;
}
</script>
<body onload="c_sayHi()">
<input type='button' value='Never Clicked'
onclick='google.script.run.withSuccessHandler(c_updateButton).withUserObject(this).s_getCurrentDate()'>
<input type='button' value='Never Clicked'
onclick='google.script.run.withSuccessHandler(c_updateButton).withUserObject(this).s_getCurrentDate()'>
</body>
</html>
Google Script file
function s_getCurrentDate() {
return new Date().toString();
}
function doGet(e) {
return HtmlService.createTemplateFromFile('hello').evaluate();
}
I have prefixed c_ to client side functions and s_ for server side fns. When running this as a web app,
Function c_sayHi has no effect - I am not sure if it is even invoked.
Functions s_getCurrentDate and c_updateButton work fine as described in google's documentation https://developers.google.com/apps-script/html_service.
Is there a way to get closure library working from the web apps as attempted above?
Couple of things here -
All .gs files is JavaScript that runs on the server side. So the DOM is not really relevant there.
You can run client side JavaScript by returning code in HtmlService. This is what I believe you want to do. However, jQuery is the best supported library on this approach. Closure might end up working but the team does not specifically test against that library.
The problem is that Closure's dependency structure is executing before the window load event, otherwise it will not work. So any require and provide statements are taken care of way before window load. When you inject them through the HTML Service, you are forcing their execution at a different stage then required, which causes everything to fail.
If you would be using a COMPILED Closure Library source, you will not have any problems with running Closure. Learn how to use the Compiler and Builder to make Closure Work properly. Also, you can use lazy loading to simulate your HTML Service.
With that, you can make javascript load dynamically onclick, onload or whatever the hell you want. This is called lazy-loading and it is used as a standard practice for all large web applications. Monitor the Network tab of Firebug when browsing through Gmail or Facebook.
Arun Nagarajan is right, jQuery is the easier solution but if you are doing something proper that requires breadth, scale and speed, jQuery is a toy for kids.