Semantic UI with React & ES6 imports - node.js

I am trying to include Semantic UI with ES6 imports inside my React component.
I am using Grunt with Babel + Browserify.
I have already installed Semantic UI via NPM.
Here is Gruntfile browserify config:
grunt.initConfig({
browserify: {
dist: {
options: {
transform: [
['babelify', {
presets: ['es2015', 'react']
}]
],
watch: true
},
files: {
'./dist/app.js': ['./src/js/app.js']
}
}
},
I have created component like this:
import React from 'react'
import $ from 'jquery'
import dropdown from 'semantic-ui'
class Container extends React.Component {
constructor() {
super()
this.state = {
value: null
}
}
componentDidMount() {
$('.ui.selection.dropdown').dropdown({
dataType: 'jsonp',
apiSettings : {
onResponse: function(githubResponse) {
var
response = {
results : []
}
;
// translate github api response to work with dropdown
$.each(githubResponse.items, function(index, item) {
response.results.push({
name: item.name,
value: item.id
});
});
return response;
},
url: '//api.github.com/search/repositories?q={query}'
},
onChange: (value) => {
this.setState({
value
});
}
});
}
componentDidUpdate() {
$('.ui.dropdown').dropdown('refresh');
}
render() {
return (
<div>
<div>
<h2>Dropdown</h2>
<div className="ui fluid multiple search selection dropdown">
<input type="hidden" name="repo-ids" />
<div className="default text">Select Repos</div>
<i className="dropdown icon"></i>
<div className="menu">
</div>
</div>
</div>
<div>
<div className="ui divider"></div>
<b>Selected value</b> {this.state.value}
</div>
</div>
);
}
};
export default Container
However, when I try to compile this code, I get:
Error: Cannot find module 'semantic-ui'
Any help ? Do I need to setup browserify somehow, to compile Semantic UI ?

Actually, there is a separate library of Semantic-UI for Reactjs. You need to install that and use it in your Reactjs application. To install just do npm install semantic-ui-react --save and you can find everything. Here is a link to its official site: semantic-ui-react

Related

Use XState in a nuxt composable

I want to use an xstate state machine in Nuxt 3 which is used over multiple components.
I created a small example of how I want this to look like.
I also use the nuxt-xstate module.
State Machine:
export default createMachine(
{
id: 'toggle',
initial: 'switched_off',
states: {
switched_on: {
on: {
SWITCH: {
target: 'switched_off'
}
}
},
switched_off: {
on: {
SWITCH: {
target: 'switched_on'
},
}
},
},
}
)
Composable:
const toggle = useMachine(toggleMachine)
export function useToggleMachine(){
return { toggle }
}
app.vue:
<template>
<div>
State: {{toggle.state.value.value}}
</div>
<br />
<button
#click="toggle.send('SWITCH')"
>
Switch
</button>
</template>
<script>
import { useToggleMachine } from '~/composables/toggle_machine'
export default {
setup(){
const { toggle } = useToggleMachine()
return { toggle }
}
}
</script>
The problem is, that I can have a look at the state of the machine {{state.value.value}} gives me the expected 'turned_off'. But I cannot call the events to transition between states. When clicking on the button, nothing happens.
Here is the console.log for the passed 'toggle' object:
Does anyone know a way how to fix this, or how to use xstate state machines over multiple components.
I am aware that props work, but I don't really want to have an hierarchical approach like that.
In Nuxt3, it's very simple:
in composables/states.ts
import { createMachine, assign } from 'xstate';
import { useMachine } from '#xstate/vue';
const toggleMachine = createMachine({
predictableActionArguments: true,
id: 'toggle',
initial: 'inactive',
context: {
count: 0,
},
states: {
inactive: {
on: { TOGGLE: 'active' },
},
active: {
// eslint-disable-next-line #typescript-eslint/no-explicit-any
entry: assign({ count: (ctx: any) => ctx.count + 1 }),
on: { TOGGLE: 'inactive' },
},
},
});
export const useToggleMachine = () => useMachine(toggleMachine);
In pages/counter.vue
<script setup>
const { state, send } = useToggleMachine()
</script>
<template>
<div>
<button #click="send('TOGGLE')">
Click me ({{ state.matches("active") ? "✅" : "❌" }})
</button>
<code>
Toggled
<strong>{{ state.context.count }}</strong> times
</code>
</div>
</template>

Vue pass parameter using handlebars

Hello i use nodejs with express and handlebars and vue 2.6
I want pass {{audioannotationid}} to my vue component but i can't,
what are i'm doing wrong?
sorry for my english
This my edit.hbs
<div> Editar audio annnotations</div>
<div id="EditAudioannotations" idParametro="beowulfdgo" >
</div>
{{audioannotationid}}
This my component
<template>
<div id="EditAudioannotations" >Hola {{who}}
{{valor}}
</div>
</template>
<script>
export default {
name: 'EditAudioannotations',
props:{idParametro:{
type: String,
default: '0',
},},
data() {
return {
who:"world",
json: {},
valor:"otro valor"
};
},
methods: {
},
beforeMount() {
},
};
</script>
<style></style>
This my index.js
if(window.location.pathname.match(/\/audioannotations\/edit\//)){
// window.Vue = Vue
Vue.use(VueAxios, axios);
Vue.component("EditAudioannotations", EditAudioannotations);
window.vm = new Vue({
el: '#EditAudioannotations',
render: h => h(EditAudioannotations)
})
}
This muy result
I resolved obtain id from url becase i don't use routex, in vue add this method
created() {
var currentUrl = window.location.pathname;
this.ruta=currentUrl
//console.log(currentUrl);
var ultimoSlash = this.ruta.lastIndexOf("/");
this.ruta=this.ruta.substring(ultimoSlash+1)
},

how to solve this no-unused-vars error in NodeJS?

I am creating a todo app using MERN stack.I am new to MERN stack technology and I kindly neeed your help solving this error.I have provided the code for my app.js file and todo.js file.I can't clearly find the solution of this error anywhere on the internet.
I am getting this error while runnng the node js app using npm start command.
Compiled with warnings.
src\App.js
Line 4:8: 'Todo' is defined but never used no-unused-vars
Search for the keywords to learn more about each warning.
To ignore, add // eslint-disable-next-line to the line before.
App.js
import React from 'react';
import logo from './logo.svg';
import './App.css';
import Todo from './components/Todo.js';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;
Todo.js
import React, { Component } from 'react'
import axios from 'axios';
// eslint-disable-next-line
export class Todo extends Component {
constructor(props) {
super(props)
this.state = {
todos : [],
item : ""
}
}
changeHandler = (event) => {
this.setState({item: event.target.value})
}
clickHandler = (event) => {
event.preventDefault()
console.log(this.state.item)
axios({
method: 'post',
url: 'http://localhost:3000/',
data: {
todo: this.state.item,
}
});
this.setState({item:''})
}
componentDidMount() {
axios.get('http://localhost:3000/').then((response) => {
console.log(response.data.data)
let data = [];
console.log(response.data.data.length)
for(var i =0; i < response.data.data.length; i++){
data.push(response.data.data[i].todo)
}
this.setState({todos: data})
});
}
componentDidUpdate() {
axios.get('http://localhost:3000/').then((response) => {
console.log(response.data.data)
let data = [];
console.log(response.data.data.length)
for(var i =0; i < response.data.data.length; i++){
data.push(response.data.data[i].todo)
}
this.setState({todos: data})
});
}
render() {
return (
<div>
<input type="text" onChange={this.changeHandler}/>
<button type="submit" onClick={this.clickHandler}>add</button>
<div>
<ul>{this.state.todos.map((todo, index) => <li key={index}>{todo}</li>)}</ul>
</div>
</div>
)
}
}
export default Todo
That warning you are getting because even though you are importing Todo file in your App.js file but you aren't using it anywhere.Either try using it in App.js or remove the import(in case you don't need it).That should fix the warning.
Or add // eslint-disable-next-line just before the import Todo.. statement in App.js

Missing "key" prop for element. (ReactJS and TypeScript)

I am using below code for reactJS and typescript. While executing the commands I get below error.
I also added the import statement
import 'bootstrap/dist/css/bootstrap.min.css';
in Index.tsx.
Is there a way to fix this issue?
npm start
client/src/Results.tsx
(32,21): Missing "key" prop for element.
The file is as below "Results.tsx"
import * as React from 'react';
class Results extends React.Component<{}, any> {
constructor(props: any) {
super(props);
this.state = {
topics: [],
isLoading: false
};
}
componentDidMount() {
this.setState({isLoading: true});
fetch('http://localhost:8080/topics')
.then(response => response.json())
.then(data => this.setState({topics: data, isLoading: false}));
}
render() {
const {topics, isLoading} = this.state;
if (isLoading) {
return <p>Loading...</p>;
}
return (
<div>
<h2>Results List</h2>
{topics.map((topic: any) =>
<div className="panel panel-default">
<div className="panel-heading" key={topic.id}>{topic.name}</div>
<div className="panel-body" key={topic.id}>{topic.description}</div>
</div>
)}
</div>
);
}
}
export default Results;
You are rendering an array of elements, so React needs a key prop (see react docs) to identify elements and optimize things.
Add key={topic.id} to your jsx:
return (
<div>
<h2>Results List</h2>
{topics.map((topic: any) =>
<div className="panel panel-default" key={topic.id}>
<div className="panel-heading">{topic.name}</div>
<div className="panel-body">{topic.description}</div>
</div>
)}
</div>
);
This has helped me
React special props should not be accessed
https://deepscan.io/docs/rules/react-bad-special-props

How can I use Esri Arcgis Map in ReactJs Project?

I'm trying to use Esri map. To include map in my project, here is what I found:
require([
"esri/map",
"esri/dijit/Search",
"esri/dijit/LocateButton",
"esri/geometry/Point",
"esri/symbols/SimpleFillSymbol",
"esri/symbols/SimpleMarkerSymbol",
"esri/symbols/SimpleLineSymbol",
But there isn't any esri folder or npm package. Therefore, I'm confused here. How esri is imported in project?
Use esri-loader to load the required esri modules. This is a component rendering basemap.
import React, { Component } from 'react';
import { loadModules } from 'esri-loader';
const options = {
url: 'https://js.arcgis.com/4.6/'
};
const styles = {
container: {
height: '100vh',
width: '100vw'
},
mapDiv: {
padding: 0,
margin: 0,
height: '100%',
width: '100%'
},
}
class BaseMap extends Component {
constructor(props) {
super(props);
this.state = {
status: 'loading'
}
}
componentDidMount() {
loadModules(['esri/Map', 'esri/views/MapView'], options)
.then(([Map, MapView]) => {
const map = new Map({ basemap: "streets" });
const view = new MapView({
container: "viewDiv",
map,
zoom: 15,
center: [78.4867, 17.3850]
});
view.then(() => {
this.setState({
map,
view,
status: 'loaded'
});
});
})
}
renderMap() {
if(this.state.status === 'loading') {
return <div>loading</div>;
}
}
render() {
return(
<div style={styles.container}>
<div id='viewDiv' style={ styles.mapDiv } >
{this.renderMap()}
</div>
</div>
)
}
}
export default BaseMap;
This renders a base map but this is not responsive. If I remove the div around the view div or if I give the height and width of the outer div (surrounding viewDiv) as relative ({ height: '100%', width: '100%'}), the map does not render. No idea why. Any suggestions to make it responsive would be appreciated.
An alternative method to the above is the one demonstrated in esri-react-router-example. That application uses a library called esri-loader to lazy load the ArcGIS API only in components/routes where it is needed. Example:
First, install the esri-loader libary:
npm install esri-loader --save
Then import the esri-loader functions in any react module:
import * as esriLoader from 'esri-loader'
Then lazy load the ArcGIS API:
componentDidMount () {
if (!esriLoader.isLoaded()) {
// lazy load the arcgis api
const options = {
// use a specific version instead of latest 4.x
url: '//js.arcgis.com/3.18compact/'
}
esriLoader.bootstrap((err) => {
if (err) {
console.error(err)
}
// now that the arcgis api has loaded, we can create the map
this._createMap()
}, options)
} else {
// arcgis api is already loaded, just create the map
this._createMap()
}
},
Then load and the ArcGIS API's (Dojo) modules that are needed to create a map:
_createMap () {
// get item id from route params or use default
const itemId = this.props.params.itemId || '8e42e164d4174da09f61fe0d3f206641'
// require the map class
esriLoader.dojoRequire(['esri/arcgis/utils'], (arcgisUtils) => {
// create a map at a DOM node in this component
arcgisUtils.createMap(itemId, this.refs.map)
.then((response) => {
// hide the loading indicator
// and show the map title
// NOTE: this will trigger a rerender
this.setState({
mapLoaded: true,
item: response.itemInfo.item
})
})
})
}
The benefit of using esri-loader over the approach shown above is that you don't have to use the Dojo loader and toolchain to load and build your entire application. You can use the React toolchain of your choice (webpack, etc).
This blog post explains how this approach works and compares it to other (similar) approaches used in applications like esri-redux.
You don't need to import esri api like you do for ReactJS. As the react file will finally compile into a js file you need to write the esri parts as it is and mix the ReactJS part for handling the dom node, which is the main purpose of ReactJS.
A sample from the links below is here
define([
'react',
'esri/toolbars/draw',
'esri/geometry/geometryEngine',
'dojo/topic',
'dojo/on',
'helpers/NumFormatter'
], function(
React,
Draw, geomEngine,
topic, on,
format
) {
var fixed = format(3);
var DrawToolWidget = React.createClass({
getInitialState: function() {
return {
startPoint: null,
btnText: 'Draw Line',
distance: 0,
x: 0,
y: 0
};
},
componentDidMount: function() {
this.draw = new Draw(this.props.map);
this.handler = this.draw.on('draw-end', this.onDrawEnd);
this.subscriber = topic.subscribe(
'map-mouse-move', this.mapCoordsUpdate
);
},
componentWillUnMount: function() {
this.handler.remove();
this.subscriber.remove();
},
onDrawEnd: function(e) {
this.draw.deactivate();
this.setState({
startPoint: null,
btnText: 'Draw Line'
});
},
mapCoordsUpdate: function(data) {
this.setState(data);
// not sure I like this conditional check
if (this.state.startPoint) {
this.updateDistance(data);
}
},
updateDistance: function(endPoint) {
var distance = geomEngine.distance(this.state.startPoint, endPoint);
this.setState({ distance: distance });
},
drawLine: function() {
this.setState({ btnText: 'Drawing...' });
this.draw.activate(Draw.POLYLINE);
on.once(this.props.map, 'click', function(e) {
this.setState({ startPoint: e.mapPoint });
// soo hacky, but Draw.LINE interaction is odd to use
on.once(this.props.map, 'click', function() {
this.onDrawEnd();
}.bind(this));
}.bind(this))
},
render: function() {
return (
<div className='well'>
<button className='btn btn-primary' onClick={this.drawLine}>
{this.state.btnText}
</button>
<hr />
<p>
<label>Distance: {fixed(this.state.distance)}</label>
</p>
</div>
);
}
});
return DrawToolWidget;
});
Below are the links where you can find information in detail.
http://odoe.net/blog/esrijs-reactjs/
https://geonet.esri.com/people/odoe/blog/2015/04/01/esrijs-with-reactjs-updated

Resources