ES6 import function - execute in Vue component - function

In my Vue app I have JS file with some config data. In JS file there is export function. I'm importing this function to my Vue component but it's returning function declaration as a string. How can I make that function to return it's return data?
JS file
export function Test(app) {
return [ some data... ]
}
Vue component
import { Test } from '#/config/Test'
export default {
data() {
return {
testData: Test,
}
},
}

Related

Not uploading CSV file in vue.js

I have started with vue and D3. I just want to show my csv data in the console but when I try to do it with D3 CSV function is not working at all. Appears an array of 16 HTML elements which are in index.html, would you mind helping me with this?
This is my project structure:
This is my component code:
<template>
</template>
<script>
import * as d3 from "d3";
import { csv } from 'd3';
export default {
name: 'mycomponent',
data() {
return{
dataset: [],
}
},
async mounted(){
const data = await d3.csv('./datasets/dataset.csv')
this.$data.$dataset = Object.freeze(data)
console.log(data);
}
}
</script>
This is home:
<template>
<mycomponent></mycomponent>
</template>
<script>
import mycomponent from '#/components/mycomponent.vue'
export default {
name: 'Home',
components: {
mycomponent,
},
}
</script>
And this is what I get in console:
The d3.csv function will execute at runtime not compile-time so you have to put your csv file in public directory then use it as usual public files.
let data = await d3.csv("/datasets/dataset.csv")
Or if you want to load your csv file at compile-time you can import it as string and use d3.csvParse instead.
import dataset from '#/datasets/dataset.csv'
let data = d3.csvParse(dataset);
I would prefer the first method, in the second method your csv file might cause your script file too big.
Example

Exclude JSON files from the main bundle with webpack for react-lottie

In our web app we have a few JSON files that are ~10-80k lines each. These are getting included in our main bundle. These are used by an animation plugin called react-lottie.
An example of our webpack.config.js
module.exports = {
entry: ["./src/index.js"],
module: {
rules: [
{ test: /\.(js|jsx)$/, exclude: /node_modules/, use: ["babel-loader"] },
{
test: /\.(jpg|png|gif|ico)$/,
use: {
loader: "file-loader",
options: { name: "[path][name].[hash].[ext]" }
}
}
]
},
resolve: { extensions: ["*", ".js", ".jsx"] },
output: {
path: __dirname + "/dist",
publicPath: "/",
filename: "[name].[hash].js"
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new HtmlWebpackPlugin({ hash: false, template: "src/index.html" }),
new DashboardPlugin(),
new CopyWebpackPlugin([
{
from: "src/components/Assets/BookingBar.js",
to: "assets/BookingBar.js"
}
]),
new BundleAnalyzerPlugin()
],
devServer: {
contentBase: "./dist",
hot: true,
historyApiFallback: true,
port: 4000
}
};
What is the expected behavior?
There should be a way to exclude .json files from the main bundle. I've tried File-Loader, json-loader, and const someJson = require(./someJson)
Other relevant information:
webpack version: 4.16.1
Node.js version: 10.12.0
Operating System: Mac OS 10.14 Mojave
ANSWER BELOW (AT LEAST FOR HOW I SOLVED IT). I couldn't initialize the lottie without any data.
The expected behavior is that the JSON will get bundled because it's, presumably, needed synchronously at runtime. JSON data differs from something like image files which are loaded asynchronously by the browser as they are rendered on the page via src attributes etc.
As the comments mentioned, you should be using code splitting. The latest version of Webpack supports dynamic imports if you install and use the #babel/plugin-syntax-dynamic-import plugin.
npm install --save-dev #babel/plugin-syntax-dynamic-import
Then in babel.config.js:
module.exports = {
...
plugins: [
"#babel/plugin-syntax-dynamic-import"
]
...
};
Example
Say you have a React component that might need some JSON data, but doesn't need to load it synchronously as part of the bundle. Your non-code splitted version might look something like this:
import React from 'react';
import myJSON from './myJSON.json';
export default class MyComponent extends React.Component {
render() {
return <div>{JSON.stringify(myJSON, null, 2)}</div>
}
}
Instead you can use a dynamic import - basically a runtime import that returns a Promise you can use to asynchronously load some data chunked separately from your bundle:
import React from 'react';
import myJSON from './myJSON.json';
export default class MyComponent extends React.Component {
state = {data: {}};
componentDidMount() {
import(/* webpackChunkName: 'myJSON' */ './myJSON.json')
.then((data) => {
this.setState({data});
});
}
render() {
return <div>{JSON.stringify(this.state.data, null, 2)}</div>
}
}
Alternately, you can use React's new lazy and Suspense API (v16.6.0 and higher) to dynamically import React components that get chunked separately from the bundle. This might be preferable if you want to chunk a component and its corresponding JSON data together, but separately from the main bundle:
// MyComponent.jsx
import React from 'react';
import myJSON from './myJSON.json';
export default class MyComponent extends React.Component {
render() {
return <div>{JSON.stringify(myJSON, null, 2)}</div>
}
}
// SomeParent.jsx
import React, {lazy, Suspense} from 'react';
const MyComponent = lazy(() => import(/* webpackChunkName: 'MyComponent' */ './MyComponent'));
export default class SomeParent extends React.Component {
render() {
return <div>
<Suspense fallback={<div>Loading...<div>} >
<MyComponent />
</Suspense>
</div>;
}
}
In the above example, <MyComponent /> and its corresponding code -- including the JSON data -- will only be loaded when the component is actually rendered at runtime.
Ultimately I took the answer above below me but wasn't able to initialize the lottie without any JSON data. I ended up doing this:
import React, { PureComponent } from "react"
import Lottie from 'react-lottie'
export default class AnimationAutomatedCommunication extends PureComponent {
constructor(props) {
super(props)
this.state = {
animation: <div />
}
}
async componentDidMount() {
const animation = await import(/* webpackChunkName: "AnimationAutomatedCommunication" */ './JsonData/AnimationAutomatedCommunication.json')
const defaultOptions = {
loop: true,
autoplay: true,
animationData: animation.default
}
this.setState({
animation: <div className={this.props.className}>
<Lottie key="lottie-win-jobs" options={defaultOptions}
isStopped={this.props.isStopped} />
</div>
})
}
render() {
return (
<React.Fragment>
{this.state.animation}
</React.Fragment>
)
}
}

Load Script Tag in Angular 2 App When Src Attribute is from Web API Call

Context:
I have an Angular 2+ application that makes calls to a web API containing URLs for a src attribute on a script tag that is created by a loadScript function in the AfterViewInit lifecycle hook.
The web API returns a JsonResult and is yielding the data I expect. I was able to interpolate some of the data in the component's template.
Additionally, before I added the call to the web API, the loadScript function was working with a hard-coded argument.
Reading a thread on github. A "member" stated that scripts are not supposed to be loaded on demand. So what I implemented with the loadScript function is essentially a work around, but how else would load them? I don't want to have a seemingly endless amount of script tags sitting in the index.html file.
import { Component, OnInit, AfterViewInit } from '#angular/core';
import { ActivatedRoute } from '#angular/router';
import { Http } from '#angular/http';
#Component({
selector: 'app-agriculture-roadmap',
templateUrl: './agriculture-roadmap.component.html',
styleUrls: ['./agriculture-roadmap.component.css']
})
export class RoadmapComponent implements OnInit, AfterViewInit {
constructor(private _httpService: Http, private _route: ActivatedRoute)
{
}
apiRoadmaps: { roadmapName: string, pdfRoadmapURL: string, jsRoadmapURL: string };
ngOnInit() {
this._httpService
.get('/api/roadmaps/' + this._route.params)
.subscribe(values => {
this.apiRoadmaps = values.json() as { roadmapName: string, pdfRoadmapURL: string, jsRoadmapURL: string };
});
}
async ngAfterViewInit() {
await this.loadScript(this.apiRoadmaps.jsRoadmapURL);
}
private loadScript(scriptUrl: string) {
return new Promise((resolve, reject) => {
const scriptElement = document.createElement('script')
scriptElement.src = scriptUrl
scriptElement.onload = resolve
document.body.appendChild(scriptElement)
})
}
}
If you are using angular cli .
Then place these scripts in
angular-cli.json file under scripts array
scripts:[
.....
]
Please refer this [link] (https://rahulrsingh09.github.io/AngularConcepts/faq)
It has a question on how to refer third party js or scripts in Angular with or without typings.

what will export { foo as bar } affect when importing module

I am confused about this snippet here.
//------ underscore.js ------
export default function (obj) {
...
};
export function each(obj, iterator, context) {
...
}
export { each as forEach };
//------ main.js ------
import _, { each } from 'underscore';
...
The export { each as forEach } part confused me.
When I import this function, should I use
import { each } from 'underscore' or import { forEach } from 'underscore'?
When I use the function in main.js , what will be the difference between export { each } and export { eash as forEach } ?
The export { each as forEach } part confused me.
It means "export the value of the local variable each under the name forEach".
When I import this function, should I use import { each } from 'underscore' or import { forEach } from 'underscore'?
import { forEach } from 'underscore'
because that's what the module exports.
When I use the function in main.js , what will be the difference between export { each } and export { eash as forEach } ?
export {each} exports the value under the name each. For the other see my first answer.
There wouldn't be any difference using the function except that you'd use a different name.
FWIW, the same thing can be done on the import side:
import { forEach as foo} from 'underscore'
Now you can refer to that function as foo instead of forEach.

Missing props in mapStateToProps

Version
4.1.1
Steps to reproduce
This component is querying a db via GraphQL thanks to Apollo. It is a GraphQL container.
It uses compose from react-apollo library in order to use multiple enhanchers at the same time, in a readable way.
Example component:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { graphql, compose, withApollo } from 'react-apollo';
import { myQuery } from './graphqlQuery';
class MyComponent extends Component {
render() {
const { exampleProp } = this.props;
return null;
}
}
function mapStateToProps(state, ownProps) {
// I expect to see ownProps.exampleProp here but it is undefined
console.log(ownProps.exampleProp);
}
export default compose(
withApollo,
connect(mapStateToProps),
graphql(myQuery),
)(MyComponent);
Expected Behavior
ownProps should contain the props passed to the component as stated here
like:
Object = {
client: ApolloClient
exampleProp: "propcontent", // <-- this is going to be lost
history: Object
location: Object
match: Object
staticContext: undefined
__proto__: Object
}
Actual Behavior
instead ownProps contains only this:
Object = {
client: ApolloClient
history: Object
location: Object
match: Object
staticContext: undefined
__proto__: Object
}
All the props that the component should have had from parents and from GraphQL response are missing, including, in this case, exampleProp.