How do you call a node.js function from a HTML page? - javascript

I'm following a node.js and Azure service bus tutorial.
I'm able to run the below as a node app, however, I am struggling to call a node function from my HTML page:
Note that all the files have correctly loaded with the node http-server module, however, when I call the main function, I get the following error:
ReferenceError: ServiceBusClient is not defined
Node.js function:
const { ServiceBusClient } = require("#azure/service-bus");
// Define connection string and related Service Bus entity names here
const connectionString ="";
const queueName = "";
async function main() {
const sbClient = ServiceBusClient.createFromConnectionString(
connectionString
);
const queueClient = sbClient.createQueueClient(queueName);
const sender = queueClient.createSender();
try {
for (let i = 0; i < 1; i++) {
const message = {
body: "{}",
label: "Contact",
userProperties: {
myCustomPropertyName: "my custom property value",
},
};
console.log(`Sending message: ${message.body}`);
await sender.send(message);
}
await queueClient.close();
} finally {
await sbClient.close();
}
}
main().catch((err) => {
console.log("Error occurred: ", err);
});
Any help much appreciated.

Summarize the comments from Pogrindis for other communities reference:
Node is backend business logic, the HTML is the front end and so there is no direct communication to the methods in Node. We could implement some webserver like express to allow http calls to be made to the node server, and from there we could call the business logic. And for the error of service bus, we need to implement the ServiceBusClientOptions interface.

To use Azure SDK libraries on a website, you need to convert your code to work inside the browser. You can do this using bundler such as rollup, webpack, parcel, etc. Refer to this bundling docs to use the #azure/service-bus library in the browsers.
Moreover, the code in your sample looks like it is using version 1.
Version 7.0.0 has been recently published. Refer to the links below.
#azure/service-bus - 7.0.0
Samples for 7.0.0
Guide to migrate from #azure/service-bus v1 to v7

Related

My Javascript file won't run because of bigint error

I am trying to use #metaplex/js to do some NFT minting. Usually my .js files work properly but when I run the file this error comes up.
bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)
I don't really get what that means. So, I tried to run npm run rebuild but rebuild is said to be a missing script and I couldn't find a way to install it.
Here is my code:
import { Connection, programs} from "#metaplex/js";
import { Loader } from "#solana/web3.js";
const { metadata: {Metadata}} = programs;
const connection = new Connection("devnet");
const tokenPublicKey = 'my_adress';
const run = async() => {
try{
const ownedMetadata = await Metadata.Loader(connection,tokenPublicKey)
console.log(ownedMetadata)
}
catch{
console.log('Failed to fetch')
}
};
run();
If you have any idea, or simply an explanation of what my error means, I'd be grateful.
You are getting this error because a nested dependency has a compilation step that might not succeed in your platform. This issue provides a good explanation.
[...] This happens because one of our dependencies (bigint-buffer) runs a compilation step on installation and this can step may fail for a couple of reasons. One of the reasons is that your system might not have the build-tools the library is looking for. You can install these build tools on Windows (see https://www.npmjs.com/package/windows-build-tools), but you don't actually need to as it automatically falls back to a pure JS solution instead. Though I agree... that warning is very annoying.
However, this should give you a warning and still allow you to compile your code.
It is worth noting that the current JS SDK from Metaplex is going to be deprecated in favour of the new one: https://github.com/metaplex-foundation/js-next
With the new JS SDK, you can fetch an NFT using the following piece of code.
import { Metaplex } from "#metaplex-foundation/js";
import { Connection, clusterApiUrl } from "#solana/web3.js";
const connection = new Connection(clusterApiUrl("mainnet-beta"));
const metaplex = new Metaplex(connection);
const mintAddress = new PublicKey("ATe3DymKZadrUoqAMn7HSpraxE4gB88uo1L9zLGmzJeL");
const nft = await metaplex.nfts().findByMint({ mintAddress });

Error: 7 PERMISSION_DENIED: Your application has authenticated using end user credentials from the Google Cloud SDK

This was working a couple months ago without code changes inside of my websocket server, however using it today it seems that the Google speech to text api no longer allows authentication using access tokens.
This was my previously working method until I hit this error today
const client = new speech.SpeechClient({
access_token: ACCESS_TOKEN,
projectId: 'project-name'
});
That nets me the above error in the title.
I also tried switching to a service account (which I used in the past) by setting up the environment as follows
export GOOGLE_APPLICATION_CREDENTIALS="path-to-key.json"
I then run the client without the above code and instead run:
const client = new speech.SpeechClient();
and that nets me this beautiful error instead, even though the environment is set at this point with the project Id
Error: Unable to detect a Project Id in the current environment.
Any help in resolving this would be much appreciated!
I resolved the environment problem and subsequent error by doing the following:
const options = {
keyFilename: 'path-to-key.json',
projectId: 'project-name',
};
const client = new speech.SpeechClient(options);
I was able to follow the Official Quickstart and got it working by using Client Libraries with no issues. I will explain what I did right below.
From Cloud Speech-to-Text - Quickstart:
Create or select a project:
gcloud config set project YOUR_PROJECT_NAME
Enable the Cloud Speech-to-Text API for the current project:
gcloud services enable speech.googleapis.com
Create a service account:
gcloud iam service-accounts create [SA-NAME] \
--description "[SA-DESCRIPTION]" \
--display-name "[SA-DISPLAY-NAME]"
Download a private key as JSON:
gcloud iam service-accounts keys create ~/key.json \
--iam-account [SA-NAME]#[PROJECT-ID].iam.gserviceaccount.com
Set the environment variable GOOGLE_APPLICATION_CREDENTIALS to the file path of the JSON file that contains your service account key:
export GOOGLE_APPLICATION_CREDENTIALS="[PATH]"
Install the Client Library
npm install --save #google-cloud/speech
Created a quickstart.js file and put the following code sample inside:
'use strict';
// [START speech_quickstart]
async function main() {
// Imports the Google Cloud client library
const speech = require('#google-cloud/speech');
const fs = require('fs');
// Creates a client
const client = new speech.SpeechClient();
// The name of the audio file to transcribe
const fileName = './resources/audio.raw';
// Reads a local audio file and converts it to base64
const file = fs.readFileSync(fileName);
const audioBytes = file.toString('base64');
// The audio file's encoding, sample rate in hertz, and BCP-47 language code
const audio = {
content: audioBytes,
};
const config = {
encoding: 'LINEAR16',
sampleRateHertz: 16000,
languageCode: 'en-US',
};
const request = {
audio: audio,
config: config,
};
// Detects speech in the audio file
const [response] = await client.recognize(request);
const transcription = response.results
.map(result => result.alternatives[0].transcript)
.join('\n');
console.log("Transcription: ${transcription}");
}
main().catch(console.error);
WHERE const fileName = './resources/audio.raw' is the path where your test.raw audio is located.

How to open a persistent SSH client to make a Web based File manager?

I am currently using shelljs to make make connection everytime it needs to use a ssh function.
class Connection {
constructor(id, path) {
this.id = id;
this.path = path;
}
exec(silent, ...args) {
const { exec } = shellJS;
const execCmd = exec(
['ssh ', ...args].join(' '),
{ silent }
);
// FormError(execCmd);
return execCmd;
}
}
class FileManager {
constructor(connection) {
this.connection = connection;
}
async ls(path = '') {
const newPath = path ? `'${path}/'` : '';
const listing = this.connection.exec(false, `"ls -l ${newPath}"`);
return parseEntries(listing.stdout);
}
}
EDIT1: After answer from brad, Mounting will may not work here, because
We have VERY limited access to that server(not sure if it can be mounted)
The code here is somewhat simplified. The real flow would be:
Local -> SSH Server
-> AnAppThatManagesCloudBuckets <command>
-> Output
Your code is subject to command injection, and is inherently insecure and likely unreliable for edge cases, like paths/filenames with reserved characters.
I would recommend a different approach entirely. Use SSHFS to mount the remote filesystem. Then, use the standard Node.js fs API to do your directory listings and such.
After some more research found 3 packages that can be used to create persitent SSH client in the background:
As #ChrisG said.
ssh2 which is basically SSH module written in JS
pty.js a pseudo terminal emulator
node-pty A fork of pty.js

"fetch is not found globally and no fetcher passed" when using spacejam in meteor

I'm writing unit tests to check my api. Before I merged my git test branch with my dev branch everything was fine, but then I started to get this error:
App running at: http://localhost:4096/
spacejam: meteor is ready
spacejam: spawning phantomjs
phantomjs: Running tests at http://localhost:4096/local using test-in-console
phantomjs: Error: fetch is not found globally and no fetcher passed, to fix pass a fetch for
your environment like https://www.npmjs.com/package/unfetch.
For example:
import fetch from 'unfetch';
import { createHttpLink } from 'apollo-link-http';
const link = createHttpLink({ uri: '/graphql', fetch: fetch });
Here's a part of my api.test.js file:
describe('GraphQL API for users', () => {
before(() => {
StubCollections.add([Meteor.users]);
StubCollections.stub();
});
after(() => {
StubCollections.restore();
});
it('should do the work', () => {
const x = 'hello';
expect(x).to.be.a('string');
});
});
The funniest thing is that I don't even have graphql in my tests (although, I use it in my meteor package)
Unfortunately, I didn't to find enough information (apart from apollo-link-http docs that has examples, but still puzzles me). I did try to use that example, but it didn't help and I still get the same error
I got the same error importing a npm module doing graphql queries into my React application. The app was compiling but tests were failing since window.fetch is not available in the Node.js runtime.
I solved the problem by installing node-fetch https://www.npmjs.com/package/node-fetch and adding the following declarations to jest.config.js:
const fetch = require('node-fetch')
global.fetch = fetch
global.window = global
global.Headers = fetch.Headers
global.Request = fetch.Request
global.Response = fetch.Response
global.location = { hostname: '' }
Doing so we instruct Jest on how to handle window.fetch when it executes frontend code in the Node.js runtime.
If you're using nodejs do the following:
Install node-fetch
npm install --save node-fetch
Add the line below to index.js:
global.fetch = require('node-fetch');
The problem is this: fetch is defined when you are in the browser, and is available as fetch, or even window.fetch
In the server it is not defined, and either needs to be imported explicity, or a polyfill like https://www.npmjs.com/package/unfetch (as suggested in the error message) needs to be imported by your test code to make the problem go away.

Is it feasible to use web worker (multi-threading) in Angular and Typescript in NativeScript?

I'm currently develop an App that is based on NativeScript and Angular2.
My screen freeze for while when my App fetching data through HTTP, and I'd like to put the fetching action into another thread.
I did a lot of search on the web, and all I got is the code in javascript like the official doc - https://docs.nativescript.org/angular/core-concepts/multithreading-model.html
Is there any way to implement the muli-threading with WebWorker in "Typescript"(which contain the support of Angular injected HTTP service) instead of the "Javascript" code(the code from the official doc)
It's appreciated if someone could give me some guide or hint, and it'll be great if I could got some relative example code.
Thanks.
There shouldn't be any big draw back for using WebWorkers in {N} + Angular but be aware that currently the WebWorker is not "exactly" compatible with Angular AoT compilation.
For me when creating an WebwWrker (var myWorker = new Worker('~/web.worker.js');) throws and error after bundling the application with AoT. I have seen soem talk about this in the community and possible the way to fix this is by editing the webpack.common.js and adding an "loaded" like so:
{
test: /\.worker.js$/,
loaders: [
"worker-loader"
]
}
Disclaimer: I have not tried this approach for fixing the error.
If someone have some problems adding workers in Nativescript with Angular and Webpack, you must follow the steps listed here.
Keep special caution in the next steps:
When you import the worker, the route to the worker file comes after nativescript-worker-loader!.
In the webpack.config.js keep caution adding this piece of code:
{
test: /.ts$/, exclude: /.worker.ts$/, use: [
"nativescript-dev-webpack/moduleid-compat-loader",
"#ngtools/webpack",
]
},
because is probable that you already have configured the AoT compilation, like this:
{
test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
use: [
"nativescript-dev-webpack/moduleid-compat-loader",
"#ngtools/webpack",
]
},
and you only need to add the exclude: /.worker.ts$/,
Finally, there is an example of a worker, in this case it use an Android native library:
example.worker.ts:
import "globals";
const context: Worker = self as any;
declare const HPRTAndroidSDK;
context.onmessage = msg => {
let request = msg.data;
let port = request.port;
let result = HPRTAndroidSDK.HPRTPrinterHelper.PortOpen("Bluetooth," + port.portName);
context.postMessage(result);
};
example.component.ts (../../workers/example.worker is the relative route to my worker):
import * as PrinterBTWorker from "nativescript-worker-loader!../../workers/example.worker";
import ...
connect(printer: HPRTPrinter): Observable<boolean> {
if (this.isConnected()){
this.disconnect(); //Disconnect first if it's already connected
}
return Observable.create((observer) => {
const worker = new PrinterBTWorker();
worker.postMessage({ port: printer });
worker.onmessage = (msg: any) => {
worker.terminate();
if (msg.data == 0) { // 0: Connected, -1: Disconnected
observer.next(true);
}
else {
observer.next(false);
}
};
worker.onerror = (err) => {
worker.terminate();
observer.next(false);
}
}).pipe(timeout(5000), catchError(err => of(false)));
}
Note: I use an Observable to make my call to the worker async and to add a timeout to the call to the native code, because in the case that it is not possible to connect to the printer (ex. it's turned off), it takes almost 10 seconds to notify, and this caused in my case the frezing of the app for all that time.
Important: It seem that it's necessary to run again the code manually every time that a change is made, because the worker isn't compiled using AoT.

Categories