Exporting/importing Json object in es6 - javascript

I am converting some ES5 code to ES6.
I have the following line somewhere in the file StatesComponent.js
const STATES = require('../data/states.js');
I am using jspm and it doesn't support require, so I would like to use ES6 import syntax instead.
The states.js file contains the following:
exports.AU = [
{ value: 'australian-capital-territory', label: 'Australian Capital Territory', className: 'State-ACT' },
{ value: 'new-south-wales', label: 'New South Wales', className: 'State-NSW' },
{ value: 'victoria', label: 'Victoria', className: 'State-Vic' },
];
exports.US = [
{ value: 'AL', label: 'Alabama', disabled: true },
{ value: 'AK', label: 'Alaska' },
{ value: 'AS', label: 'American Samoa' },
];
STATES variable is being used as var options = STATES[this.state.country];
How do I change the format of the json in states.js such that I can `import' it?
i.e import STATES from '../data/states'

Not sure if you got the answer to this already but you can export it as:-
export default {
STATES: {
'AU' : {...},
'US' : {...}
}
};
to which you can import as:-
import STATES from 'states';
or
var STATES = {};
STATES.AU = {...};
STATES.US = {...};
export STATES;
to which you can import as:-
import { STATES } from 'states';
Notice the difference between one that uses default and one that doesn't. With default you can export any javascript expression and during import you can use whatever identifier and it will be defaulted to that default expression.
You could also have done
import whatever from 'states';
and whatever would get the value of an object that we assigned to default.
In contrast, when you don't export default expression, export exports it as an part of object which is why you had to use
import {STATES}
In this case you HAVE to use the right literal name for import to work or else import will not be able to understand what you're trying to import. Also, note that it's using object destructuring to import the right value.
And like #AlexanderT said, there are ways to import as * too, in fact there are various ways to import and export but I hope I explained the core concept of how this import/export works.

Related

vue3: how to add a globalProperties which is base on $attr

In vue3, I try to add attributes like $attrsWithoutIdClassStyle and $attrsIdClassStyleOnly to the globalProperties which the values are based on the $attrs of current vue-component
It can be achieved by the global mixins
import _ from 'lodash';
import { createApp } from 'vue';
import App from '~/App.vue';
createApp(App)
mixin({
computed: {
$attrsWithoutIdClassStyle() {
return _.omit(this.$attrs, ['id', 'class', 'style']);
},
$attrsIdClassStyleOnly() {
return _.pick(this.$attrs, ['id', 'class', 'style']);
},
}
})
But since the mixin is not recommended in vue3 any more, also the code is ugly.
So, how can I add the custom attributes to the global properties via app-config-globalproperties which is a dynamic value based on the current vm?
As the documentation suggests, the proper Vue 3 replacement is to use a composable function and import where needed.
composables/myAttrs.js
import { useAttrs } from 'vue';
import _ from 'lodash';
export function useMyAttrs() {
const attrs = useAttrs();
const attrsWithoutIdClassStyle = _.omit(attrs, ['id', 'class', 'style']);
const attrsIdClassStyleOnly = _.pick(attrs, ['id', 'class', 'style']);
return {
attrsWithoutIdClassStyle,
attrsIdClassStyleOnly
};
}
in your components,
import { useMyAttrs } from '#/composables/myAttrs';
const { attrsWithoutIdClassStyle, attrsIdClassStyleOnly } = useMyAttrs();

VueJS - "this" is undefined in common function

I'm trying to extract a function for use across multiple components, but "this" is undefined and I'm unsure of the best practice approach of how to attach the scope so my function knows what "this" is. Can I just pass it as an argument?
Component:-
import goToEvent from "#/common";
export default {
name: "update",
methods: {
goToEvent
common function:-
let goToEvent = (event, upcoming=false) => {
this.$store.dispatch({
type: 'setEventsDay',
day: event.start_date
})
}
export default goToEvent
When I call goToEvent in my component, I get TypeError: Cannot read property '$store' of undefined. How do I avoid this?
In this situation I recommend to define eventable as a mixin :
const eventable= {
methods: {
goToEvent(event, upcoming=false) {
this.$store.dispatch({
type: 'setEventsDay',
day: event.start_date
})
}
}
}
export default eventable;
in your vue file :
import eventable from "#/eventable";
export default {
name: "update",
mixins:[eventable],
....
second solution :
export an object with the function as nested method then import it and spread it inside the methods option :
export default {
goToEvent(event, upcoming=false){
this.$store.dispatch({
type: 'setEventsDay',
day: event.start_date
})
}
}
then :
import goToEvent from "#/common";
export default {
name: "update",
methods: {
...goToEvent,
otherMethod(){},
}
//....
}
You're tagged with Typescript, so you need to tell TS that this actually has a value (note, I do not know VueJS, am using the generic Event types here, there is likely a more valid and correct type!)
First option, manually tell it what there is -
let goToEvent = (this:Event, event, upcoming=false) => {
Other option - tell it what type it is -
let goToEvent: EventHandler = (event, upcoming=false) => {
Of the two I personally prefer the second style for readability.
There are numerous ways to achieve this, here are some that I like to use in my projects:
Method 1: Mixins
Mixins are great for sharing a bunch of methods across components and also easy to implement, although one big con is that you will not be able to import specific methods that you need. Within the mixin, this follows the rules as in components.
File: #/mixins/eventable
import { mapActions } from 'vuex'
export default {
methods: {
...mapActions([])
goToEvent (event, upcoming = false) {
store.dispatch({
type: 'setEventsDay',
day: event.start_date
})
}
}
}
Usage in component:
import eventable from '#/mixins/eventable'
export default {
name: 'ComponentName',
mixins: [eventable],
methods: {
componentMethod () {
this.goToEvent()
}
}
...
Method 2: Static JavaScript files
In some cases, you might have a collection of helper functions kept in a file and want the ability to import as you need.
In your case, you seem to be using a store actions (assumed from the dispatch), hence I'll be including importing and using the store within the static JS file.
File: #/static/js/eventable.js
import store from 'path_to_store_file'
const goToEvent = () => {
store.dispatch('actionName', payload)
}
export default {
goToEvent
}
Note:
Although this is not entirely necessary, but only by declaring the imported function as a method within the component will it be bound to the component instance. This will allow you to access the function in the HTML portion.
Usage in component:
import { goToEvent } from '#/static/js/eventable.js'
export default {
name: 'ComponentName',
methods: {
// Read note before this code block
goToEvent,
componentMethod () {
// When declared as a method
this.goToEvent()
// When not declared, it can still be accessed in the js portion like this
goToEvent()
}
}
...

Can't import JSON in react

I'm having what I'm sure it's a stupid problem but I can't seem to find a way around it.
I have a react application and I'm trying to import a JSON file. Here it is:
{
"words":{
"ita":[
"ora",
"via",
"dio",
"sud",
"don",
"zia"
]
}
}
And here's the react code:
import React, { Component} from 'react'
import words from 'Assets/Words.json'
console.log(words)
console.log(words.ita)
export default class WordsGen extends Component {
...
The two console.log print, respectively:
{words: {…}}
words:
ita: (6) ["ora", "via", "dio", "sud", "don", "zia"]
__proto__: Object
__proto__: Object
and undefined.
I'm using the json file to put more languages in the app, but I can't understand why when I print just words I can see the property ita inside, and when I try to print words.ita or words["ita"] I get undefined.
What am I missing?
Should be:
words.words.ita
You are importing as "words" and then the object has a words object. It might be more clear to change the import name:
import MyJson from 'my.json';
console.log(MyJson.words.ita)
Because your imported object words contains whole json. When you write
import words from 'Assets/Words.json';
it will become
words = {
words:{
ita:[
"ora",
"via",
"dio",
"sud",
"don",
"zia"
]
}
}
That's why your object words doesn't really have property ita. That's why it will return undefined.
You need to write words.words.ita. For better code-style:
/// words.json
{
"ita":[
"ora",
"via",
"dio",
"sud",
"don",
"zia"
]
}
import words from 'Assets/Words.json';
words.ita // then your code
/// or even better with new es6 destructing
import {ita = []} from 'Assets/Words.json';
ita // do anything that you want

Dummy database, Exporting more than one default

So, guys, I am trying to create a dummy database that for a project I am working on, now I will take a Todo app as an example.
const todos = [
{
id: 1,
title: "lunch",
description: "Go for lunc by 2pm"
}
];
export default todos;
this is quite alright! but when I create let's say a Todo list and a list of items to be bought from a store-
const todos = [
{
id: 1,
title: "lunch",
description: "Go for lunc by 2pm"
}
const shoppingList = [
{
id: 1,
item: "lunch",
description: "Go for lunc by 2pm"
}
];
export default todos;
export default shoppingList;
if I try to run this I get this error message
"Only one default export allowed per module. (90:0- which is the last line from what I have given above
)"
module.exports = {
todos: function() {return todos},
shoppingList : function {return shoppingList }
}
You are using two exports with default either use only single export with default passing all components inside like:
export default {todos, shoppingList};
As only one export default is allowed.
Or you can put both components into one root component and export it.
If you still plan to use two different export statements just remove default keyword from it. Hope that helps.
You can also refer here for more detailed understanding:
exporting modules

StencilJS export custom class

Is there any way to force StencilJS to export enums in order to be used by regular JavaScript code?
Generated JavaScript file exports the component classes only.
export { Calendar, CalendarDailyView, CalendarMonthlyView, CalendarWeeklyView, CalendarYearlyView };
It does not export other classes or Enums defined using JavaScript.
let's say an Enum is defined in TypeScript as follows:
export enum ViewType {
daily = 0,
weekly = 1,
monthly = 2,
yearly = 3
}
the generated JavaScript file contains:
var ViewType;
(function (ViewType) {
ViewType[ViewType["daily"] = 0] = "daily";
ViewType[ViewType["weekly"] = 1] = "weekly";
ViewType[ViewType["monthly"] = 2] = "monthly";
ViewType[ViewType["yearly"] = 3] = "yearly";
})(ViewType || (ViewType = {}));
how to force StencilJS to add ViewType to the exported types list?
Enum is entirely a TypeScript concept. JavaScript has no concept of Enums, and the generated code you see is the 'best' solution that TypeScript can generate, given all of the functionality TypeScript Enums have.
To make it compatible with plain old JavaScript it might be worth declaring ViewType as a basic array, e.g.
export const ViewType = [
{ id: 1, name: 'Day' },
{ id: 2, name: 'Month' },
{ id: 3, name: 'Year' }
];
Much easier to interpret in JS than the compiled TypeScript, and a better solution if you're going to be rendering any of these data to the screen.
To make this answer Stencily, here's my example in use:
list-items.ts
export const ListItems = [
{ id: 1, name: 'Day' },
{ id: 2, name: 'Month' },
{ id: 3, name: 'Year' }
];
my-dropdown.tsx
import { Component, State } from '#stencil/core';
import { ListItems } from './list-items';
#Component({
tag: 'my-dropdown'
})
export class MyDropdown {
#State() state: { selectedId?: number } = {};
private onSelectedValueChanged(evt: UIEvent) {
this.state = { ...this.state, selectedId: parseInt((evt.target as HTMLInputElement).value) };
}
render() {
return (
<div>
<select onChange={this.onSelectedValueChanged.bind(this)}>
<option>Please select...</option>
{ListItems.map(i => <option value={i.id}>{i.name}</option>)}
</select>
<br />Selected ID: {this.state.selectedId}
</div>
);
}
}
Important: To reuse your exported collection or enum in other applications, be sure to build as dist (see outputTargets documentation in your stencil.config.js.
In this example, building as dist will include the separate export in /dist/collection/my-dropdown/list-items.js so that it can be re-used in other dependent apps and libraries.

Categories