Read file inside current directory using Vue - javascript

I'm trying to get text file data located in the same directory where my .vue file is. But it's not returning the text on both chrome and firefox. Instead it's returning following response, which is not the content of my text file.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>router-project</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
<script type="text/javascript" src="/app.js"></script></body>
</html>
Following is my vue file.
<template>
<body>
<div> hello world </div>
</body>
</template>
<script>
var $ = require('jquery');
window.jQuery = $;
export default {
data () {
return {
}
},
created () {
this.getPoemList(),
},
methods: {
getPoemList () {
function reqListener () {
console.log(this.responseText);
}
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("GET", "hello.txt");
oReq.send();
} // getPoemList function ends
} // methods end
} // export default ends
</script>
<style scoped>
</style>
Contents of hello.txt are following.
hello

I assume you're using Webpack, since you have a .vue file (requiring the vue-loader Webpack plugin)...
You can use raw-loader to load the .txt file as a string.
Install raw-loader from NPM with:
npm i -D raw-loader
In <projectroot>/vue.config.js, configure Webpack to use raw-loader for *.txt:
module.exports = {
//...
chainWebpack: config => {
config.module
.rule('raw')
.test(/\.txt$/)
.use('raw-loader')
.loader('raw-loader')
.end()
},
}
In your component's .vue file, use import or require to load hello.txt:
<script>
import helloText from './hello.txt'; // OR: const helloText = require('./hello.txt')
export default {
//...
methods: {
getPoemList () {
console.log({ helloText });
}
}
}
</script>

<template>
<body>
<div> hello world {{variable}}</div>
</body>
</template>
<script>
var $ = require('jquery');
window.jQuery = $;
export default {
data() {
return {
variable: "",
}
},
mounted() {
methods: {
// create a vm variable pointing this
const vm = this;
function reqListener() {
// captures the local value this.responseText to vm (this vuejs) vm.variable
vm.variable = this.responseText;
console.log(this.responseText);
}
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("GET", "hello.txt");
oReq.send();
}
}
}
</script>
<style> </style>

Related

electron js - cannot get button to perform simple actions from click

Long story short I am working on a single page application that sends commands over a local network. Testing out Electron JS and I can't even seem to get a simple button to work. I feel like I am not linking the logic between main.js and index.js somehow but for the life of me I cannot figure out the correct way to do it. I have even put breakpoints in index.js and through main.js & index.html but none of the breakpoints are hit aside from the ones in main.js. I put a simple function in a preload.js file and that function is correctly called but the one I am trying to attach to a button located in index.html and index.js is never even being hit. A lot of the commented out code is things I want to remember or things I have noticed a different method of creating and just wanted to try and see if that worked. If anyone has any answers or guidance it would be greatly appreciated! :D
Below is my main.js
//#region ---for dev only | hot reload
try {
require('electron-reloader')(module)
} catch (_) {}
//#endregion
const electron = require('electron');
const {app, BrowserWindow, Menu} = require('electron');
const path = require('path');
const ipcMain = electron.ipcMain;
//#region globals
const SRC_DIR = '/src/'
const IMG_DIR = '/assets/images'
//#endregion
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
//frame: false,
webPreferences: {
contextIsolation: true,
preload: path.join(__dirname, 'preload.js')
}
});
//Used to auto open dev tools for debugging
//win.openDevTools();
win.loadFile('src/index.html');
// win.loadURL(url.format({
// pathname: path.join(__dirname, 'index.html'),
// protocol: 'file',
// slashes: true
// }));
}
app.whenReady().then(() => {
//nativeTheme.shouldUseDarkColors = true;
createWindow();
})
//closes app processes when window is closed
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit();
})
var menu = Menu.buildFromTemplate([
{
label: 'Menu',
submenu: [
{label: 'Edit'},
{type: 'separator'},
{
label: 'Exit',
click() {
app.quit();
}
}
]
}
])
Menu.setApplicationMenu(menu);
Here is index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<meta http-equiv="X-Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<title>Ecas Software</title>
<link rel="stylesheet" href="index.css">
</head>
<body>
<p id="myText">Let's get started :)</p>
<button id="myBtn">Change Text</button>
<script type="text/javascript" src="./index.js" ></script>
</body>
</html>
Lastly here is my index.js (aka my first and only renderer?)
const electron = require('electron');
const chgBtn = document.getElementById('myBtn');
function replaceText(selector, text){
const element = document.getElementById(selector);
if (element) element.innerText = text;
}
chgBtn.onclick = function() {
replaceText('myText', 'no boom...');
}
// chgBtn.addEventListener('click', function(){
// // if (document.getElementById('myText').innerText == 'boom'){
// // replaceText('myText','no boom...');
// // } else {
// // replaceText('myText','boom');
// // }
// document.alert("working function");
// });
//chgBtn.addEventListener('click', replaceText('myText','no boom...'));
Why you have this error
The problem here is that you didn't use your scripts files the way Electron was intended.
If you use the Devtools Console (by uncommenting win.openDevTools()), you should see this error in your console :
Uncaught ReferenceError: require is not defined (from index.js file)
This is because your index.js file is loaded as a "normal javascript file". If you want to use the Node syntaxe (aka the "require" syntaxe), you need to do it in your preload script. Only the preload script can use the require syntaxe, since it is the only script allowed by Electron to use Node.
You can also use other javascripts files, by import it in your HTML as you did for the index.js file, but you should remove the require call. As the "require" call (on the first line) will throw and error, all the following code will not run. This is why your button did not react on click.
The correct way to do it
If you need to use some methods from the Electron Renderer API (such as the ipcRenderer), you need to put it in your preload script.
If you want to use your own script, in a separate file, you can also do it, you will not be able to directly call Electron API. There is a solution if you want to call the Electron API in your own script, it is called the Context Bridge. This allows you to create an object in your preload script, that can use the Electron API. You can give this object a name, and then call it from your others script by using the window global object.
For example, if you want to use ipcRenderer.send(channel, payload) :
// Preload script
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('theNameYouWant',
{
send: (channel, payload) => ipcRenderer.send(channel, payload)
}
)
// index.js file, imported in your HTML file
window.theNameYouWant.send("channel-name", { someData: "Hello" })
In your example
// Add this in your main.js file to see when a user click on the button from main process
ipcMain.on("button-clicked", (event, data) => console.log(data))
// Preload script
const { contextBridge, ipcRenderer } = require("electron")
contextBridge.exposeInMainWorld("electron", {
send: (channel, payload) => ipcRenderer.send(channel, payload),
})
// index.js
const chgBtn = document.getElementById("myBtn")
function replaceText(selector, text) {
const element = document.getElementById(selector)
if (element) element.innerText = text
}
chgBtn.onclick = function () {
replaceText("myText", "no boom...")
window.electron.send("button-clicked", { someData: "Hello" })
}

Issue interfacing smart contract with the front end

I'm actually trying to write a simple smart contract with front end that takes a value from the user and saves that in the variable in the smart contract.
The index.html part of my project is
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Example</title>
<!-- Bootstrap -->
<link href="css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div id="message"></div>
<form method="POST">
<div><input id= "message" name = "message" type= "text">
</div>
<div>
<button type="button" id="register">Register</button>
</div>
</div>
</form>
<script src="js/bootstrap.min.js"></script>
<script src="js/web3.min.js"></script>
<script src="js/truffle-contract.js"></script>
<script src="js/app.js"></script>
</body>
</html>
And app.js is
App = {
web3Provider: null,
contracts: {},
account: '0x0',
init: function() {
return App.initWeb3();
},
initWeb3: function() {
if (typeof web3 !== 'undefined') {
// If a web3 instance is already provided by Meta Mask.
App.web3Provider = web3.currentProvider;
web3 = new Web3(web3.currentProvider);
} else {
// Specify default instance if no web3 instance provided
App.web3Provider = new Web3.providers.HttpProvider('http://localhost:7545');
web3 = new Web3(App.web3Provider);
}
return App.initContract();
},
initContract: function() {
$.getJSON("HelloWorld.json", function(hello) {
// Instantiate a new truffle contract from the artifact
App.contracts.HelloWorld = TruffleContract(hello);
// Connect provider to interact with contract
App.contracts.HelloWorld.setProvider(App.web3Provider);
return App.bindEvents();
});
},
bindEvents: function() {
$(document).on('click', '#register', function(){ var msg = $('#message').val(); App.handleMessage(msg); });
},
handleMessage: function(msg){
var hwinstance;
App.contracts.HelloWorld.deployed().then(function(instance) {
hwinstance = instance;
return hwinstance.setMessage(msg);
}).then( function(result){
if(result.receipt.status == '0x01')
alert("successfully")
else
alert("failed due to revert")
}).catch( function(err){
alert("failed")
})
}
};
$(function() {
$(window).load(function() {
App.init();
console.log('starting app.js');
});
});
The smart contract code that I've written is
pragma solidity 0.5.16;
contract HelloWorld {
string private message = "hello world";
function getMessage() public view returns(string memory) {
return message;
}
function setMessage(string memory newMessage) public {
message = newMessage;
}
}
When I ran the commands truffle complie and truffle migrate, it showed no errors but when I ran 'npm run dev' the page says "Cannot GET /".
I'm not able to understand where the mistake is. Please help!
Is there any other way of interfacing the frontend to the smart contract?
Your local server cannot find your page either because it is in the wrong directory or the local server has not been installed. Run npm install --save-dev lite-server. In the package.json you should have something like
"script": {
"dev": "lite-server",
...
}
Move your index.html and App.js into src/ directory you create at the root of the project. Run npm run dev to check again. It should work. If you are interested in an easy to use truffle box with react, I have developed a truffle box with React + Material-UI. Take a look here https://github.com/rouftom/truffle-react-material

How do I dynamically load a YAML file as an object in a VuePress Vue Component?

I'm trying to embed SwaggerUI into my vuepress site. I got this far
<template><div :id="id">swagger</div>
</template>
<script>
// import { SwaggerUIBundle, SwaggerUIStandalonePreset } from "swagger-ui-dist"
import SwaggerUI from "swagger-ui";
import x from '#/upload-api.yml'
export default {
props: {
src: String
},
data() {
return {
id: null,
spec: {}
};
},
mounted() {
this.id = `swagger${this._uid}`;
// over here, I want to use `this.src` to pull the data
console.log(x);
},
updated() {
if (this.id !== null) {
SwaggerUI({
domNode: this.$el,
// dom_id: `#${this.id}`,
spec: this.spec,
});
}
}
};
</script>
<style></style>
In my plugin I have:
const path = require('path');
module.exports = {
chainWebpack (config, isServer) {
config.module
.rule("compile")
.test(/\.ya?ml$/)
.type("json")
.use("yaml")
.loader("yaml-loader");
config.resolve.alias.set("#", path.resolve("."));
Here's some other things I tried
console.log(require(this.src));
which gets me
[Vue warn]: Error in mounted hook: "Error: Cannot find module '#/upload-api.yml'"
This works though
console.log(require("#/upload-api.yml"));
I ended up doing the following
I also tried a solution similar to Static image src in Vue.js template
# Upload
<SwaggerUi :spec="require('#/upload-api.yml')" />
<template>
<div>swagger</div>
</template>
<script>
import SwaggerUI from "swagger-ui";
export default {
props: {
spec: Object
},
mounted() {
SwaggerUI({
domNode: this.$el,
spec: this.spec
});
}
};
</script>
<style>
#import "~swagger-ui/dist/swagger-ui.css";
</style>
And a plugin
const path = require('path');
module.exports = {
chainWebpack (config, isServer) {
config.module
.rule("compile")
.test(/\.ya?ml$/)
.type('json')
.use("yaml")
.loader("yaml-loader");
config.resolve.alias.set("#", path.resolve("."));
// config is an instance of ChainableConfig
},
}
upload-api.yml
openapi: "3.0.2"
info:
title: OpenWeatherMap
version: '1.0'
paths:
/weather:
get:
Which gives me:

How to load local JavaScript file with JSDOM?

I am unable to use JSDOM (version 13.0.0) to load scripts from the local filesystem with a relative path.
I have taken a look at the following questions but they do not answer my question:
jsdom can't load local html and javascript (I have already followed the runScripts and resources suggestion there).
File foo.js:
var jsdom = require('jsdom')
var html = `<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<script src="bar.js"></script>
</head>
<body>
<div>Test</div>
</body>
</html>`
global.window = new jsdom.JSDOM(html, { runScripts: "dangerously", resources: "usable" }).window
console.log('foo')
File bar.js:
console.log('bar')
Here is the error I get:
$ node foo.js
foo
Error: Could not load script: "bar.js"
at onErrorWrapped (/Users/lone/so/node_modules/jsdom/lib/jsdom/browser/resources/per-document-resource-loader.js:41:19)
at Object.check (/Users/lone/so/node_modules/jsdom/lib/jsdom/browser/resources/resource-queue.js:72:23)
at request.then.catch.err (/Users/lone/so/node_modules/jsdom/lib/jsdom/browser/resources/resource-queue.js:124:14)
at process._tickCallback (internal/process/next_tick.js:68:7)
at Function.Module.runMain (internal/modules/cjs/loader.js:746:11)
at startup (internal/bootstrap/node.js:240:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:564:3) Error: Tried to fetch invalid URL bar.js
at ResourceLoader.fetch (/Users/lone/so/node_modules/jsdom/lib/jsdom/browser/resources/resource-loader.js:84:29)
at PerDocumentResourceLoader.fetch (/Users/lone/so/node_modules/jsdom/lib/jsdom/browser/resources/per-document-resource-loader.js:16:42)
at HTMLScriptElementImpl._fetchExternalScript (/Users/lone/so/node_modules/jsdom/lib/jsdom/living/nodes/HTMLScriptElement-impl.js:92:30)
at HTMLScriptElementImpl._eval (/Users/lone/so/node_modules/jsdom/lib/jsdom/living/nodes/HTMLScriptElement-impl.js:161:12)
at HTMLScriptElementImpl._poppedOffStackOfOpenElements (/Users/lone/so/node_modules/jsdom/lib/jsdom/living/nodes/HTMLScriptElement-impl.js:126:10)
at OpenElementStack.pop (/Users/lone/so/node_modules/jsdom/lib/jsdom/browser/htmltodom.js:17:12)
at Object.endTagInText [as END_TAG_TOKEN] (/Users/lone/so/node_modules/parse5/lib/parser/index.js:2153:20)
at Parser._processToken (/Users/lone/so/node_modules/parse5/lib/parser/index.js:657:55)
at Parser._processInputToken (/Users/lone/so/node_modules/parse5/lib/parser/index.js:684:18)
at Parser._runParsingLoop (/Users/lone/so/node_modules/parse5/lib/parser/index.js:440:18)
How can I load a local JavaScript file while using JSDOM?
JSDOM doesn't know where to look for that file locally while executing. So running your example you can follow any of this two approaches.
1st Approach
You have to wait for the script file to load and execute.
Create a three files index.html,index.js and test.js into the same folder.
index.html
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
abc
<script src='index.js'></script>
</body>
</html>
index.js
document.body.textContent = 123;
test.js
'use strict';
const { JSDOM } = require('jsdom');
const options = {
resources: 'usable',
runScripts: 'dangerously',
};
JSDOM.fromFile('index.html', options).then((dom) => {
console.log(dom.window.document.body.textContent.trim());
setTimeout(() => {
console.log(dom.window.document.body.textContent.trim());
}, 5000);
});
// console output
// abc
// 123
2nd Approach
Set the external scripts base root folder in JSDOM env.
js/index.js
console.log('load from jsdom');
var loadFromJSDOM = 'load from jsdom';
test.js
'use strict';
const { JSDOM } = require('jsdom');
JSDOM.env({
html: "<html><body></body></html>",
documentRoot: __dirname + '/js',
scripts: [
'index.js'
]
}, function (err, window) {
console.log(window.loadFromJSDOM);
}
);
Read more from these references
https://github.com/jsdom/jsdom/issues/1867
jsdom.env: local jquery script doesn't work
Great answer from front_end_dev. It helped me a lot and I will share how my code works with this solution to be more clear. Maybe will help others.
import "#testing-library/jest-dom";
import { logDOM } from "#testing-library/dom";
import { JSDOM } from "jsdom";
import fs from "fs";
import path from "path";
const html = fs.readFileSync(path.resolve(__dirname, "../index.html"), "utf8");
let dom;
let container;
jest.dontMock("fs");
function waitForDom() {
return new Promise((resolve) => {
dom = new JSDOM(html, {
runScripts: "dangerously",
resources: "usable",
url: `file://${path.resolve(__dirname, "..")}/index.html`,
});
dom.window.document.addEventListener("DOMContentLoaded", () => {
resolve();
});
});
}
beforeAll(() => waitForDom());
beforeEach(() => {
container = dom.window.document.body;
});
afterEach(() => container = null)
it("should ", () => {
logDOM(container);
});

Specify directory name with HapiJS

I want to include my local CSS/JavaScript file in res.response () of hapiJS. I am not able to load my local file. How can I load my local file in the response of Hapi? How to specify directory name?
module.exports = function (req, res) {
Router.run(routes, req.url.path , function (Handler) {
var content = React.renderToString(React.createElement(Handler, { state: '' }));
var head = <link href="/css/app.caz.css" rel="stylesheet"/></script> <script src="js/app.caz.js"></script>;
var page = ` <!DOCTYPE html> <html> ${head} <body> </body> </html>`;
res.response(page);
});
};

Categories

Resources