Importing JSON file from inside Vue.JS method - Electron - javascript

I am using a json file to load/write some data. This specific JSON file gets changed quite often.
So with this, how can I import this JSON file from inside a Vue.JS method?
Currently I do this:
<script>
import * as settings from '../config/settings.json'
// some other things
</script>
But this only gets the json file once and I am not able to get the updates on the json file anymore.
I tried doing something like this:
methods: {
loadJsonFile () {
import * as settings from '../config/settings.json'
}
}
But it gives an error:
error Parsing error: 'import' and 'export' may only appear at the top level
How can I dynamically get the updates on this json file based on some trigger (e.g. calling of a method)? Only on code level - not allowed to get modules for this.
Thanks

Related

Elixir Phoenix - How to create and import javascript files into specific templates

I'm currently experimenting with the Elixir Phoenix framework together with Liveview. For my project, I would like to write some Javascript code that is only imported on certain pages (templates). Although this seems like something very trivial, I am struggling to get it working.
At this moment I created a seperate Javascript file as such assets/js/custom.js. After doing this, I added the following line to my root.html.heex as a first test to see if this already works. For this line, I simply looked at how app.js is imported.
<script defer phx-track-static type="text/javascript" src={Routes.static_path(#conn, "/assets/custom.js")}></script>
The next step would then be to figure out how to import it in a seperate template instead of the root. However, this first test already failed resulting in the following error:
[debug] ** (Phoenix.Router.NoRouteError) no route found for GET /assets/custom.js (MyAppWeb.Router)
(my_app 0.1.0) lib/phoenix/router.ex:405: MyAppWeb.Router.call/2
(my_app 0.1.0) lib/my_app_web/endpoint.ex:1: MyAppWeb.Endpoint.plug_builder_call/2
(my_app 0.1.0) lib/plug/debugger.ex:136: MyAppWeb.Endpoint."call (overridable 3)"/2
(my_app 0.1.0) lib/my_app_web/endpoint.ex:1: MyAppWeb.Endpoint.call/2
(phoenix 1.6.15) lib/phoenix/endpoint/cowboy2_handler.ex:54: Phoenix.Endpoint.Cowboy2Handler.init/4
(cowboy 2.9.0) c:/Users/arnod/Desktop/phoenixtut/my_app/deps/cowboy/src/cowboy_handler.erl:37: :cowboy_handler.execute/2
(cowboy 2.9.0) c:/Users/arnod/Desktop/phoenixtut/my_app/deps/cowboy/src/cowboy_stream_h.erl:306: :cowboy_stream_h.execute/3
(cowboy 2.9.0) c:/Users/arnod/Desktop/phoenixtut/my_app/deps/cowboy/src/cowboy_stream_h.erl:295: :cowboy_stream_h.request_process/3
(stdlib 4.0.1) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
Could somebody help me figure this one out? How does one add seperate Javascript files and only import them in specific templates?
You can import all your custom javascript once in app.js, assign them as hooks which you can then use in your (live) views, wherever needed, for example;
custom.js
export const SomeFunction = {
mounted() {
alert("some function ran!");
}
}
app.js snippet
...
import {SomeFunction} from "./custom.js"
let Hooks = {}
Hooks.SomeFunction = SomeFunction
let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
let liveSocket = new LiveSocket("/live", Socket, {params: {_csrf_token: csrfToken}, hooks: Hooks})
...
Then in your live view render function (or template) add the hook
...
def render(assigns) do
~H"""
...
<div id="my-hook" phx-hook="SomeFunction"></div>
...
end
...
More about javascript interoperability can be found on the Phoenix hex page here. You can tie them to all sorts of phoenix events.
nb. Also note that #conn isn't available in live views, only #socket is.

Trouble with using an npm package (leaflet addon) in html <script> tag

I am trying to include a leaflet package in my locally hosted website. The idea of the website is to allow the user to query for tweets from the Twitter API (the request is sent fro the HTML page to a NodeJs server running on express) and have these sent back and loaded in the leaflet map using a bounding box to place the marker. Since most tweets don't come with a geotag or bounding box information, I thought the next best thing would be to take the name of the location (e.g. London) stored in the tweet metadata and do a reverse geocoding to get the bounding box from the city/location name. To do this reverse geocoding I thought I would use a leaflet add-on called leaflet-geosearch, since the other common option of using the Google Maps API seem not to be free. I have tried now many ways of importing this package into my project, but all with no luck. The documentation shows that it can be loaded using
// import
import { OpenStreetMapProvider } from 'leaflet-geosearch';
// setup
const provider = new OpenStreetMapProvider();
// search
const results = await provider.search({ query: input.value });
So I tried to load it in this fashion in my HTML code inside of a tag as such:
<script type="module">
import { OpenStreetMapProvider } from 'leaflet-geosearch';
// setup
const provider = new OpenStreetMapProvider();
</script>
But it tells me that I need to add a '/' for a relative pathway. So I tried to load it using a relative path to numerous different scripts in the node_modules/leaflet-geosearch folder:
<script type="module">
import { OpenStreetMapProvider } from './node_modules/leaflet-geosearch/dist/geosearch.js';
// setup
const provider = new OpenStreetMapProvider();
</script>
The above method told me that "'geosearch.js' does not provide an export named 'OpenStreetMapProvider'", so I went back and looked through the files some more and found a file named 'openStreetMapProvider.js' and so tried to load this:
<script type="module">
import { OpenStreetMapProvider } from './node_modules/leaflet-geosearch/lib/providers/openStreetMapProvider.js';
// setup
const provider = new OpenStreetMapProvider();
</script>
But it gave me the same error "... does not provide an export named 'OpenStreetMapProvider'".
I have tried to load it directly into my nodeJS server script,
// import
const OpenStreetMapProvider = require('leaflet-geosearch');
// setup
const provider = new OpenStreetMapProvider();
But when I then try to run the server on a local port it throws the Reference error below.
Does anyone know how I could properly load and use this module in my HTML page? I have seen some answers that say browserify can help in such cases, but if that was really necessary then the ReadME on the package's github page should have mentioned this, so I feel like there must be a more straightforward solution to this.

Include JSON files into React build

I know this question maybe exist in stack overflow but I didn't get any good answers, and I hope in 2020 there is better solution.
In my react app I have a config JSON file, it contains information like the title, languages to the website etc..
and this file is located in 'src' directory
{
"headers":{
"title":"chat ",
"keys":"chat,asd ,
"description":" website"
},
"languages":{
"ru":"russian",
"ar":"arabic",
"en":"English"
},
"defaultLanguage":"ru",
"colors":{
"mainColor":"red",
"primary":"green",
"chatBackGround":"white"
}
}
I want to make my website easy to edit after publishing it, but after I build my app, I can't find that settings.json file there in build directory.
I find out that files in public directory actually get included to build folder, I tried to put my settings.JSON in public,
but react won't let me import anything outside of src directory
I found other solutions like this one but didn't work
https://github.com/facebook/create-react-app/issues/5378
Also I tried to create in index.html a global var like (window.JSON_DATA={}), and attach a JS object to it and import it to App.js, but still didn't work.
How can I make a settings JSON file, and have the ability to edit it after publishing the app?
Add your settings.json to the public folder. React will copy the file to the root of build. Then load it with fetch where you need it to be used. For example if you need to load setting.json to the App.js then do the next:
function App() {
const [state, setState] = useState({settings: null});
useEffect(()=>{
fetch('settings.json').then(response => {
response.json().then(settings => {
// instead of setting state you can use it any other way
setState({settings: settings});
})
})
})
}
If you use class-components then do the same in componentDidMount:
class CustomComponent extends React.Component {
constructor(props) {
super(props);
this.state = {settings: null};
}
componentDidMount() {
fetch('settings.json').then(response => {
response.json().then(settings => {
this.setState({settings: settings});
})
})
}
}
Then you can use it in render (or any other places of your component):
function App() {
...
return (
{this.state.settings && this.state.settings.value}
)
}
The easiest way would be to require() the file on the server during server side rendering of the html page and then inline the json in the html payload in a global var like you mentioned window.JSON_DATA={}. Then in your js code you can just reference that global var instead of trying to use import.
Of course this approach would require you to restart your server every time you make a change to the json file, so that it get's picked up. If that is not an option then you'll need to make an api call on the server instead of using require().
You may want to look at using npm react-scripts (https://www.npmjs.com/package/react-scripts) to produce your react application and build. This will package will create a template that you can put your existing code into and then give you a pre-configure build option that you can modify if you would like. The pre-configured build option will package your .json files as well. Check out their getting started section (https://create-react-app.dev/docs/getting-started/)
If you don't want to go that route, and are just looking for quick fix, then I would suggest change your json files to a JS file, export the JS object and import it in the files you need it since you seem to be able to do that.
//src/sampledata.js
module.exports = {
sample: 'data'
}
//src/example.jsx (this can also be .js)
const sampledata = require('./sampledata');
console.log(sampledata.sample); // 'data'
you can use 'Fetch Data from a JSON File'
according to link
https://www.pluralsight.com/guides/fetch-data-from-a-json-file-in-a-react-app
example

Can't import local json file in angular 5

I'm trying to import a local file to use the data in it.
I have tried the require method and the import method. Neither seems to work.
I'm using Angular 5 and Typescript 2.9.2. I am locked to angular 5.
I'm building for aot and when I look at the fesm5 file that gets exported the json file does not seem to resolve.
(I DO NOT WANT TO PULL IT IN WITH HTTP...)
import * as data from '../../assets/file.json';
When I try to set tsconfig value to:
"resolveJsonModule": true,
I get an error on build:
Cannot read property 'slice' of undefined
TypeError: Cannot read property 'slice' of undefined
at addReferencesToSourceFile (/Users/ME/Projects/PROJECT/node_modules/#angular/compiler-cli/src/transformers/compiler_host.js:520:54)
at TsCompilerAotCompilerTypeCheckHostAdapter.getSourceFile (/Users/ME/Projects/PROJECT/node_modules/#angular/compiler-cli/src/transformers/compiler_host.js:348:13)
I have also tried the:
declare module '*.json' {
const value: any;
export default value;
}
This doesn't seem to help at all.
Also tried:
declare function require(url: string);
var data = require('../../assets/file.json');
This does not seem to resolve the json in the final file either.
You can put your file under assets folder and get it using HTTP GET from HttpClient module, this will return the whole json file, use your file path in your GET request URL; something like this:
this.http.get('../assets/file.json')
.subscribe(jsonFormat => {
//Your code
});
You can create a service for all the GET, POST, PUT& DELETE implementations. Then in your GET method of HttpClient that is imported from ‘#angular/common/http’, call the JSON with the link to your local JSON file.
public getAbout(): Observable<any> {
return this.http.get("./assets/json/about.json");
}

Webpack 4 how to require sources as separated chunks and load them on demand

I have noticed that when I am importing source in the old way, like this: require('./my-script') it injects the code of the script into the main bundle.js.
And when I am importing like this: import('./my-script')
it created a separate new file and I even can name it with:
import(/* name.js */ './my-script');
That is nice, but in the new way of using import instead of require - how can I send parameters to the imported function?
For example, in require I could do require('./my-script')('something');
However this cannot be achieved using import
How can I pass parameters to an imported function and make it as a separate chunk in webpack?
This is the my-script.js (for example only):
// my-script.js
module.exports = str => {
return `${str} was returned`;
}
import(name) is used for code splitting (creating separate chunks) and will return a promise for the module's exports once the chunk has been retrieved asynchronously.
With your example, it can be used with something like the following:
import('./my-script').then(myScript => myScript.default('hello'))
The Dynamic imports section provides a more complete example and describes how import() is used for code splitting and here in Magic Comments are options listed which you can use to control how the chunk is created and when it's retrieved so you can tweak the user experience.

Categories

Resources