I'm a beginner at Spark AR and I'm trying to build a blink counting game and I got the following error when I try to merge Scene and Patches.
Property 'text' does not exist on type 'Promise<SceneObjectBase>'.
here's my code
const Scene = require('Scene');
const Patches = require('Patches');
// Use export keyword to make a symbol available in scripting debug console
export const Diagnostics = require('Diagnostics');
(async function () { // Enables async/await in JS [part 1]
// To access scene objects
const [directionalLight] = await Promise.all([
Scene.root.findFirst('directionalLight0')
]);
var textScore = Scene.root.findFirst('score_number');
var patchScore = Patches.outputs.getScalar('ScoreJumps');
// To access class properties
const directionalLightIntensity = directionalLight.intensity;
// To log messages to the console
textScore.text = patchScore.toString();
Diagnostics.log('Console message logged from the script.');
})(); // Enables async/await in JS [part 2]
findFirst is a Promise so you need to await on it:
const textScore = await Scene.root.findFirst('score_number');
Finally,
I was able to solve my issue by adding #ts-ignore to my code as follows.
const Scene = require('Scene');
const Patches = require('Patches');
// Use export keyword to make a symbol available in scripting debug console
export const Diagnostics = require('Diagnostics');
// To use variables and functions across files, use export/import keyword
// export const animationDuration = 10;
// Use import keyword to import a symbol from another file
// import { animationDuration } from './script.js'
(async function () { // Enables async/await in JS [part 1]
// To access scene objects
const [directionalLight] = await Promise.all([
Scene.root.findFirst('directionalLight0')
]);
var countNum = await Scene.root.findFirst('number');
var scoreNumber = (await Patches.outputs.getScalar('score'));
// To access class properties
const directionalLightIntensity = directionalLight.intensity;
// #ts-ignore
countNum.text = scoreNumber.toString();
// #ts-ignore
Diagnostics.log("wererwerwe"+countNum.text);
// To log messages to the console
Diagnostics.log('Console message logged from the script.');
})(); // Enables async/await in JS [part 2]
Related
This question already has answers here:
How can I use modules in the browser, but also refer to variables and functions from within DevTools?
(4 answers)
Closed yesterday.
Update:
Looks like by importing another JS file and using the ES6 Modules, devtools compiles a bit different (will need to dive into learning more). The variables I thought were global were not in the module. Was able to fix this by assigning them to:
window.variable_name = variable_name
This allowed me to call the variables from devtools.
I have a project I am working on to practice a few JS skills. For the most part I have everything up and running but have come across an issue I can not seem to remedy.
I have an app.js file that is linked in my index.html. When running the live server from VS code everything works as it should, but when I open devtools to check some of the variables (global) & functions I get "Uncaught referenceError: variable_name is not defined" with a VM#:# reference.
Up to today, I have been able to call the variables from console without a problem.
I have 12 global variables, and all but 1 (submit) have this issue.
App.js:
import { autocomplete } from "./autocomplete.js";
// ######## GLOBAL VARIABLES ############
//------- Selectors ----------
const container = document.querySelector('.search-container');
const searchElement = document.getElementById('search');
const searchInput = document.querySelector('input[name="search-bar"]');
const submit = document.getElementById('search-bar');
const loader = document.querySelector('.loader');
const results = document.querySelector('.results');
const resetButton = document.querySelector('.reset');
const errorMessage = document.querySelector('.error');
const heart = document.querySelector('#favorite');
//------- Arrays & Objects ----------
let names = [];
let pokemon = {};
let bgImages = ["./resources/images/forest_background.jpg", "./resources/images/field.jpg", "./resources/images/galar-scenery.png", "./resources/images/night.jpg", "./resources/images/training.jpg", "./resources/images/poke-background.webp"];
//########## Grab & Store Pokemon Names for Autocomplete ##########
async function loadPokeNames() {
try {
const response = await fetch ('https://pokeapi.co/api/v2/pokemon?limit=250');
if (response.ok) {
const jsonResponse = await response.json();
// console.log(jsonResponse)
for (const poke of jsonResponse.results){
names.push(poke.name);
}
}
// throw new Error('Request Failed!')
} catch(error){
console.log(error);
}
}
//############ Search Function ###############
async function searchPokemon(e) {
e.preventDefault();
let pokeSearchValue = e.srcElement[0].value.toLowerCase();
searchElement.hidden = true;
loader.hidden = false;
try {
const pokeResponse = await fetch(`https://pokeapi.co/api/v2/pokemon/${pokeSearchValue}`);
if (pokeResponse.ok) {
const pokeJSON = await pokeResponse.json();
// Assign Values to Pokemon Object
pokemon.name = pokeJSON["name"];
pokemon.img = pokeJSON["sprites"]["other"]["official-artwork"]["front_default"];
pokemon.hp = pokeJSON["stats"][0]["base_stat"];
pokemon.attack = pokeJSON["stats"][1]["base_stat"];
pokemon.speed = pokeJSON["stats"][5]["base_stat"];
pokemon.defense = pokeJSON["stats"][2]["base_stat"];
pokemon.special_attack = pokeJSON["stats"][3]["base_stat"];
pokemon.special_defense = pokeJSON["stats"][4]["base_stat"];
console.log(pokemon);
createPokeCard(pokemon);
} else {
throw new Error("Something Went Wrong.");
}
} catch (error) {
loader.hidden = true;
errorMessage.hidden = false;
resetButton.hidden = false;
console.log(error);
}
}
// ####### Generates the Pokemon Card #########
function createPokeCard(object) {
const pokeName = document.querySelector('#poke-name p');
const pokeHP = document.querySelector('#hp');
const pokeImg = document.querySelector('#poke-image img');
const pokeAttack = document.querySelector('#attack .num');
const pokeSpeed= document.querySelector('#speed .num');
const pokeDefense = document.querySelector('#defense .num');
const pokeSpecialA = document.querySelector('#special-attack .num');
const pokeSpecialD = document.querySelector('#special-defense .num');
const backgroundImage = document.querySelector('#poke-image')
// Assign values to Results Card
backgroundImage.style.backgroundImage = `url('${bgImages[Math.floor(Math.random() * 6)]}')`;
pokeName.textContent = object.name;
pokeHP.textContent = `${object.hp} HP`;
pokeImg.src = object.img;
pokeAttack.innerText = object.attack;
pokeDefense.textContent = object.defense;
pokeSpeed.textContent = object.speed;
pokeSpecialA.textContent = object.special_attack;
pokeSpecialD.textContent = object.special_defense;
setTimeout(() => {
loader.hidden = true;
results.hidden = false;
resetButton.hidden = false;
}, 3000)
}
// ####### Resets Search & Card #########
function resetSearch() {
searchInput.value = '';
resetButton.hidden = true;
results.hidden = true;
searchElement.hidden = false;
errorMessage.hidden = true;
for (const att in pokemon){
delete pokemon[att];
}
}
//######## Favorite Functions ###########
function hoverFav() {
this.src = '../resources/images/heartline-fill.png';
}
function hoverOutFav() {
this.src = '../resources/images/heartline.png';
}
// ########### EVENTS ##############
window.onload = loadPokeNames;
autocomplete(searchInput, names)
heart.addEventListener('mouseenter', hoverFav);
heart.addEventListener('mouseout', hoverOutFav);
resetButton.addEventListener('click', resetSearch);
submit.addEventListener('submit', searchPokemon);
Linked (correct path) script tag:
<script src="./script/app.js" type="module"></script>
Any help or a point in the right direction would be amazing.
Tried calling global variables from devtools. Got an uncaught referenceError message.
Alright, so I have made a bit of digging around and it turns out the reason this happens is indeed because you're setting the type of the script as a module. Scripts that are run as modules are under strict mode by default, thus they don't allow access to global variables.
Also, they are made to run as a separate scripts(modules) and so any variables defined or imported into them are private by default and are not accessible to the global scope.
As for the error, in normal standard JS scripts, the access of a variable not defined properly(without let/const) will not throw an error, under strict mode however, it converts it into an error and throws it.
Take a look here for more info on differences between standard & module scripts. Also here for info on strict mode.
So I followed some tutorial on converting a tensorflow model (downloaded from tensorflow hub) to a tfjs model with binary and json files. When I try to use loadLayersModel() it throws a error. When I try to use loadGraphModel(), it loads and runs but the predictions dont seem to work or be meaningful in anyway. How can I tell which method to load models? I need some direction on how to troubleshoot or some recommended workflow particularly in tensorflowJS. I am using this in React Native with expo project. not sure if that matters.
TensorflowHub : https://tfhub.dev/google/aiy/vision/classifier/food_V1/1
my code:
import * as tf from '#tensorflow/tfjs'
import { bundleResourceIO, decodeJpeg } from '#tensorflow/tfjs-react-native'
import * as FileSystem from 'expo-file-system';
const modelJSON = require('./TFJS/model.json')
const modelWeights = require('./TFJS/group1-shard1of1.bin')
export const loadModel = async () => {
const model = await tf.loadLayersModel(
bundleResourceIO(modelJSON, modelWeights)
).catch((e) => {
console.log("[LOADING ERROR] info:", e)
})
return model
}
export const transformImageToTensor = async (uri)=>{
//read the image as base64
const img64 = await FileSystem.readAsStringAsync(uri, {encoding:FileSystem.EncodingType.Base64})
const imgBuffer = tf.util.encodeString(img64, 'base64').buffer
const raw = new Uint8Array(imgBuffer)
let imgTensor = decodeJpeg(raw)
const scalar = tf.scalar(255)
//resize the image
imgTensor = tf.image.resizeNearestNeighbor(imgTensor, [192, 192])
//normalize; if a normalization layer is in the model, this step can be skipped
const tensorScaled = imgTensor.div(scalar)
//final shape of the rensor
const img = tf.reshape(tensorScaled, [1,192,192,3])
return img
}
export const getPredictions = async (image)=>{
await tf.ready()
const model = await loadModel()
const tensor_image = await transformImageToTensor(image)
// const predictions = await makePredictions(1, model, tensor_image)
const prediction = await model.predict(tensor_image)
console.log(prediction)
console.log(prediction.datasync()[0])
return prediction
}
If its a layers model, you you 'loadLayersModel and if its a graph model, you use 'loadGraphModel - they are NOT interchangable and you CANNOT load a model using different method.
So if it loads using loadGraphModel, it is a graph model - as simple as that.
the predictions dont seem to work or be meaningful in anyway
This does not help - what do you expect and what do you actually get?
I am trying to implement a simple library to offload given tasks to a pool of web-workers. To do so, I am using the eval operator inside the worker to evaluate stringified functions that come from the main thread. To do so I am leveraging the webpack's plugin worker-plugin to automatically bundle workers inside the application.
First of all, I format the task to normalize arrow functions, class members, and standard functions
function format_task(task: string): string
{
if(task.indexOf('=>') !== -1)
return task;
if(task.indexOf('function') !== -1)
return `(function ${task.slice('function'.length).trim()})`;
return `(function ${task})`;
}
Then, I simply eval the resulting function calling it:
self.onmessage = (event: MessageEvent) =>
{
const {task, data} = event.data;
const formatted_task = format_task(task);
const runnable_task = eval(formatted_task);
const result = await runnable_task(...data);
self.postMessage(result);
}
The main usage would be something like:
const pool = new WorkerPool(new Worker('./worker.ts'), 10);
const task = (a: number, b: number) => a + b;
const worker_task = await pool.create_task(task);
const result = await worker_task.run(42, 12);
So far, so good. The WorkerPool instance is handling a pool of 10 workers, the function gets executed in one of them, and the result gets returned to the main thread.
The problem comes in when I try to use an external dependency inside the task as
import {toUpper} from 'lodash';
const pool = new WorkerPool(new Worker('./worker.ts'), 10);
const task = (a: number, b: number) =>
{
return toUpper('Result is ') + (a + b));
}
const worker_task = await pool.create_task(task);
const result = await worker_task.run(42, 12);
In this case, I get that lodash_1.toUpper is not defined inside the worker. The only solution would be to manually import the same function also inside the worker environment (it works). However, I would like to keep the web-worker implementation as clean as possible for the final user. Something like:
const context: Worker = self as any;
(async () =>
{
const pool_worker = new PoolWorker(context.postMessage.bind(context));
context.onmessage = pool_worker.on_message.bind(pool_worker);
await pool_worker.run();
})().catch(console.error);
I tried importing the needed libraries inside the main worker file but it does not work.
import {toUpper} from 'lodash';
const context: Worker = self as any;
(async () =>
{
const pool_worker = new PoolWorker(context.postMessage.bind(context));
context.onmessage = pool_worker.on_message.bind(pool_worker);
await pool_worker.run();
})().catch(console.error);
It only works if I import it inside the PoolWorker class.
Can you think of a way to "pass" dependencies to the PoolWorker instance letting it importing it through webpack without writing a custom webpack loader/plugin?
Thank you in advance
I'm using tensorflow js in node and trying to encode my inputs.
const tf = require('#tensorflow/tfjs-node');
const argparse = require('argparse');
const use = require('#tensorflow-models/universal-sentence-encoder');
These are imports, the suggested import statement (ES6) isn't permitted for me in my node environment? Though they seem to work fine here.
const encodeData = (tasks) => {
const sentences = tasks.map(t => t.input);
let model = use.load();
let embeddings = model.embed(sentences);
console.log(embeddings.shape);
return embeddings; // `embeddings` is a 2D tensor consisting of the 512-dimensional embeddings for each sentence.
};
This code produces an error that model.embed is not a function. Why? How do I properly implement an encoder in node.js?
load returns a promise that resolve to the model
use.load().then(model => {
// use the model here
let embeddings = model.embed(sentences);
console.log(embeddings.shape);
})
If you would rather use await, the load method needs to be in an enclosing async function
const encodeData = async (tasks) => {
const sentences = tasks.map(t => t.input);
let model = await use.load();
let embeddings = model.embed(sentences);
console.log(embeddings.shape);
return embeddings; // `embeddings` is a 2D tensor consisting of the 512-dimensional embeddings for each sentence.
};
I am using the chromeless headless browser on AWS Lambda.
I'm trying to figure out how to paginate content, but I'm new to node and async/await.
This is my code:
const Chromeless = require('chromeless').default
async function run() {
const chromeless = new Chromeless({})
var results = [];
const instance = await chromeless
.goto('https://www.privacyshield.gov/list')
for (i = 0; i < 3; i++)
{
console.log('in for');
instance
.html()
.click('a.btn-navigate:contains("Next Results")')
.wait(3000)
results.push(html)
}
await chromeless.end()
}
run().catch(console.error.bind(console))
but I get the error:
TypeError: Cannot read property 'html' of undefined
which means instance is not defined outside of await. I don't wait to create separate instances in each for loop iteration, as I would lose my position on the page.
It took some time to figure it out but was interesting, this is my first await async code from node too.
const { Chromeless } = require('chromeless')
async function run() {
const chromeless = new Chromeless()
let curpos = chromeless
chromeless.goto('https://www.privacyshield.gov/list')
.press(13)
.wait(3000);
const page1 = await curpos.html()
curpos = curpos.click('a.btn-navigate')
.wait(3000);
const page2 = await curpos.html()
curpos = curpos.click('a.btn-navigate')
.wait(3000);
const page3 = await curpos.html()
console.log(page1)
console.log("\n\n\n\n\n\n\n")
console.log(page2)
console.log("\n\n\n\n\n\n\n")
console.log(page3)
await chromeless.end()
}
run().catch(console.error.bind(console))
I hope you can take it to the loop from there.
Interestingly I was able to convert into ES5 code and debug it out.
Hope it helps.