I'm currently trying to develop a system that's using ES6 syntax, although when compiling I'm getting the error
GameSettingsStore.js: 'return' outside of function
The current code I've got is:
File index.js
import GameSettingsStore from '../stores/GameSettingsStore';
File GameSettingsStore.js
// Packages
import _ from 'lodash';
// Modules
import AppDispatcher from '../dispatcher/AppDispatcher';
import { Constants } from '../constants/AppConstants';
import * as Events from '../lib/events';
import Clib from '../game-logic/clib';
const CHANGE_EVENT = 'change';
/*
* Display Settings
*/
let _controlsSize = Clib.localOrDef('controlsSize', 'big');
let _graphMode = Clib.localOrDef('graphMode', 'graphics');
let _controlsPosition = Clib.localOrDef('controlsPosition', 'right');
let _leftWidget = Clib.localOrDef('leftWidget', 'players');
/*
* HotKeys
*/
let _hotkeysActive = false;
/*
* Ignore Clients
*/
const _ignoredClientList = JSON.parse(Clib.localOrDef('ignoredList', '{}'));
/*
* Store
*/
const GameSettingsStore = _.extend({}, Events, {
emitChange() {
this.trigger(CHANGE_EVENT);
},
addChangeListener(callback) {
this.on(CHANGE_EVENT, callback);
},
removeChangeListener(callback) {
this.off(CHANGE_EVENT, callback);
},
_setGraphMode(graphMode) {
_graphMode = graphMode;
localStorage.graphMode = graphMode;
},
_setControlsSize(controlsSize) {
_controlsSize = controlsSize;
localStorage.controlsSize = controlsSize;
},
_toggleHotkeysState() {
_hotkeysActive = !_hotkeysActive;
localStorage.hotKeysActive = _hotkeysActive;
},
_ignoreUser(username) {
_ignoredClientList[username.toLowerCase()] = { username };
localStorage.ignoredList = JSON.stringify(_ignoredClientList);
},
_approveUser(username) {
username = username.toLowerCase();
if (_ignoredClientList[username]) {
delete _ignoredClientList[username];
localStorage.ignoredList = JSON.stringify(_ignoredClientList);
}
},
getState() {
return {
graphMode: _graphMode,
controlsSize: _controlsSize,
controlsPosition: _controlsPosition,
leftWidget: _leftWidget,
hotkeysActive: _hotkeysActive
};
},
getIgnoredClientList() {
return _ignoredClientList;
}
});
AppDispatcher.register((payload) => {
const { action } = payload;
switch (action.actionType) {
case Constants.ActionTypes.SET_CONTROLS_SIZE:
GameSettingsStore._setControlsSize(action.controlsSize);
GameSettingsStore.emitChange();
break;
case Constants.ActionTypes.SET_GRAPH_MODE:
GameSettingsStore._setGraphMode(action.graphMode);
GameSettingsStore.emitChange();
break;
case Constants.ActionTypes.TOGGLE_HOYTKEYS_STATE:
GameSettingsStore._toggleHotkeysState();
GameSettingsStore.emitChange();
break;
case Constants.ActionTypes.IGNORE_USER:
GameSettingsStore._ignoreUser(action.username);
GameSettingsStore.emitChange();
break;
case Constants.ActionTypes.APPROVE_USER:
GameSettingsStore._approveUser(action.username);
GameSettingsStore.emitChange();
break;
default:
GameSettingsStore.emitChange();
break;
}
return true;
});
return GameSettingsStore;
I'm assuming the error is coming from the fact I'm not exporting my function, although I'm unsure how I'd go about doing that because of my AppDispatcher code if that is the issue.
export or export default instead of return
Related
So, I have been trying to create a litte frontend to backend communication with NextJS and NodeJs.NextJS Api forks a node and this node then listens for requests i make from my api.However, my object crashes or something, idk why.
Here is the code of my node. the process.send(NET_PONG_PACKAGE); starts the communication and tells the api , he is ready for requests, so just you dont wonder. If the API sends the first message, the "message" event is triggered and an error occurs.
import * as Utils from './util'
import {ConnectionHandler} from "./ConnectionHandler";
import {
KafkaMessagePackage,
KafkaResultPackage, NET_KAFKARESPONSE_PACKAGE,
NET_PONG_PACKAGE, NetworkPackage,
NOT_ENOUGH_ARGUMENTS_ERROR, PACKAGECODE_PING_PACKAGE,
SyncPackage, UNKNOWN_PACKAGE_ID, WRONG_NODE_TYPE_ERROR
} from "./Variables";
import {Manager} from "./KafkaManager";
const nprocess = require("node:process")
const prefix = "[NODEJS] "
// Argument Handling
const args:Array<string> = nprocess.argv;
const arg:string = args[2];
if(arg == undefined || arg != '-f'){
Utils.killProcess(nprocess,NOT_ENOUGH_ARGUMENTS_ERROR);
}
class myClass {
public validateMyRequest(json_message:any){
const message:NetworkPackage = json_message != undefined ? json_message : JSON.parse(json_message);
switch (message.reqID) {
case PACKAGECODE_PING_PACKAGE:
this.sendProcessCreatedPackage();
break;
case 0:
this.sendKafkaRequest(message);
this.sendKafkaResponsePackage();
break;
default:
this.logError(prefix + UNKNOWN_PACKAGE_ID)
break;
}
}
private sendKafkaRequest(message:any) {
const kafkaManager:Manager = new Manager(message.hostIP);
kafkaManager.sendMessageToKafka(message.topic,message.message);
}
private sendKafkaResponsePackage() {
if(!process.send){
this.logError(prefix + WRONG_NODE_TYPE_ERROR);
return;
}
this.sendMessage(NET_KAFKARESPONSE_PACKAGE);
}
private sendProcessCreatedPackage(){
this.sendMessage(NET_PONG_PACKAGE)
}
private sendMessage(messagePacke:KafkaResultPackage):void
private sendMessage(messagePackage:SyncPackage):void {
if(process.send){
process.send(messagePackage);
}
}
private logError(errorMessage:string):void{
console.log(errorMessage)
}
}
process.on("message", validateMyRequest)
// #ts-ignore
process.send(NET_PONG_PACKAGE);
This code results in following error:
this.sendKafkaRequest(message);
^
TypeError: this.sendKafkaRequest is not a function
at process.validateMyRequest (/Users/marvin.kaiser/kafka-producer/backend/build/myProducer.js:52:22)
at process.emit (node:events:525:35)
at emit (node:internal/child_process:937:14)
at process.processTicksAndRejections (node:internal/process/task_queues:83:21)
This is the code without using an object. It works just perfectly fine If you have a clue on whats going on, please let me know.
import * as Utils from './util'
import {
KafkaMessagePackage,
KafkaResultPackage, NET_KAFKARESPONSE_PACKAGE,
NET_PONG_PACKAGE, NetworkPackage,
NOT_ENOUGH_ARGUMENTS_ERROR, PACKAGECODE_PING_PACKAGE,
SyncPackage, UNKNOWN_PACKAGE_ID, WRONG_NODE_TYPE_ERROR
} from "./Variables";
import {Manager} from "./KafkaManager";
const nprocess = require("node:process")
const prefix = "[NODEJS] "
// Argument Handling
const args:Array<string> = nprocess.argv;
const arg:string = args[2];
if(arg == undefined || arg != '-f'){
Utils.killProcess(nprocess,NOT_ENOUGH_ARGUMENTS_ERROR);
}
function validateMyRequest(json_message:any){
const message:NetworkPackage = json_message != undefined ? json_message : JSON.parse(json_message);
switch (message.reqID) {
case PACKAGECODE_PING_PACKAGE:
sendProcessCreatedPackage();
break;
case 0:
logError("noch alles fein!");
console.log("Hier soll es anscheinend zu einem Fehler kommen:");
console.log(message);
sendKafkaRequest(message);
sendKafkaResponsePackage();
break;
default:
logError(prefix + UNKNOWN_PACKAGE_ID)
break;
}
}
function sendKafkaRequest(message:any) {
const kafkaManager:Manager = new Manager(message.hostIP);
kafkaManager.sendMessageToKafka(message.topic,message.message);
}
function sendKafkaResponsePackage() {
if(!process.send){
logError(prefix + WRONG_NODE_TYPE_ERROR);
return;
}
sendMessage(NET_KAFKARESPONSE_PACKAGE);
}
function sendProcessCreatedPackage(){
sendMessage(NET_PONG_PACKAGE)
console.log("Hier isst noch alles fein 1!")
}
function sendMessage(messagePackage:any):void {
if(process.send){
console.log("[NODE] Nachricht gesendet:")
console.log(messagePackage);
process.send(messagePackage);
}
}
function logError(errorMessage:string):void{
console.log(errorMessage)
}
process.on("message",validateMyRequest)
// #ts-ignore
process.send(NET_PONG_PACKAGE);
I'm trying to abstract some repetitive functions to update parts of the Monaco edit from various check boxs in the UI. The example below enables or disables linenumber in the editor.
Works fine when the editor and functions are in the same setup. When I abstract to a composable per below the editor is null, therefore does not work. Any thoughts or ideas?
Note: Some code is removed for brevity
MainTemplate.vue
import * as monaco from 'monaco-editor';
import useCodeEditor from '../composables/codeEditorFunctions';
import { ref, onMounted, reactive, inject, watch } from 'vue';
export default {
setup(props, { emit }) {
let meditor = null;
onMounted(() => {
checkDarkModeIsSet();
checkLineNumbersIsSet();
checkMiniMapIsSet();
const codeEditorDiv = document.getElementById('pf-c-code-editor__code-pre');
meditor = monaco.editor.create(codeEditorDiv, {
value: ['function x() {', '\tconsole.log("If you see this, something went wrong!");', '}'].join('\n'),
language: 'yaml',
lineNumbers: lineNumbers.value,
roundedSelection: false,
scrollBeyondLastLine: true,
readOnly: false,
theme: darkmode.value,
scrollBeyondLastLine: false,
automaticLayout: true,
wordWrap: 'on',
wrappingStrategy: 'advanced',
minimap: {
enabled: true
}
});
if (props.viewstate.editid === 0) {
getDefaultCodeBlock();
} else {
showCodeBlock();
}
getModel(props.viewstate.editid);
});
const { darkmode, checkDarkModeIsSet, toggleEditorDarkMode, lineNumbers, checkLineNumbersIsSet, toggleEditorLineNumbers } = useCodeEditor(monaco, meditor);
return {
darkmode,
lineNumbers,
toggleEditorDarkMode,
toggleEditorLineNumbers,
toggleEditorMinimap,
showConfigFullScreen
};
}
};
codeEditorFunctions.js
import { ref, reactive } from "vue";
export default function useCodeEditor(monaco, meditor) {
/** EDITOR DARKMODE */
const darkmode = ref('vs');
function checkDarkModeIsSet() {
if (localStorage.getItem('editordarkmode') === null) {
darkmode.value = 'vs';
localStorage.setItem('editordarkmode', darkmode.value);
} else {
darkmode.value = localStorage.getItem('editordarkmode');
}
}
function toggleEditorDarkMode(event) {
if (event.target.checked) {
darkmode.value = 'vs-dark';
localStorage.setItem('editordarkmode', darkmode.value);
} else {
darkmode.value = 'vs';
localStorage.setItem('editordarkmode', darkmode.value);
}
monaco.editor.setTheme(darkmode.value);
}
/** EDITOR LINNUMBERS */
const lineNumbers = ref('on');
function checkLineNumbersIsSet() {
if (localStorage.getItem('editorlineNumbers') === null) {
lineNumbers.value = 'on';
localStorage.setItem('editorlineNumbers', lineNumbers.value);
} else {
lineNumbers.value = localStorage.getItem('editorlineNumbers');
}
}
function toggleEditorLineNumbers(event) {
if (event.target.checked) {
lineNumbers.value = 'on';
localStorage.setItem('editorlineNumbers', lineNumbers.value);
} else {
lineNumbers.value = 'off';
localStorage.setItem('editorlineNumbers', lineNumbers.value);
}
meditor.updateOptions({
lineNumbers: lineNumbers.value
});
}
return {
darkmode,
checkDarkModeIsSet,
toggleEditorDarkMode,
lineNumbers,
checkLineNumbersIsSet,
toggleEditorLineNumbers,
};
};
Basically, function toggleEditorLineNumbers(event) throws an error becuase meditor (meditor.updateOptions) is null.
ANy ideas?
This is the case for a ref, which basically is a recipe that allows to pass arbitrary value by reference. Since meditor isn't supposed to be used prior to useCodeEditor call, it makes more sense to define it inside a composable instead of providing it as an argument:
function useCodeEditor(monaco) {
const meditor = ref(null);
...
return {
meditor,
...
}
}
The following code traverses an object and its keys. It does a thing for each key depending on what kind of value it refers to. It works well. All is good.
const obj = {
prop1: {
prop2: 1,
prop3: {
prop4: 2
}
},
prop5: "1"
}
function inspectRecursively(node) {
switch (typeof node) {
case "object":
handleObject(node);
break;
case "string":
handleString(node);
break;
case "number":
handleNumber(node);
break;
default:
break;
}
}
function handleObject(node) {
console.log(JSON.stringify(node, null, 2))
for (const [key] of Object.entries(node)) {
inspectRecursively(node[key]);
}
}
function handleString(node) {
console.log(node)
}
function handleNumber(node) {
console.log(node.toString().padStart("0", 3))
}
inspectRecursively(obj)
Say that I think that the file has grown too large. I split it up into modules
main.js
import { importRecursively } from "./importRecursively"
const obj = {
prop1: {
prop2: 1,
prop3: {
prop4: 2
}
},
prop5: "1"
}
inspectRecursively(obj)
importRecursively.js
import { handleObject } from "./handleObject.js"
import { handleString} from "./handleString.js"
import { handleNumber} from "./handleNumber.js"
function inspectRecursively(node) {
switch (typeof node) {
case "object":
handleObject(node);
break;
case "string":
handleString(node);
break;
case "number":
handleNumber(node);
break;
default:
break;
}
}
handleObject.js
import { importRecursively } from "./importRecursively"
function handleObject(node) {
console.log(JSON.stringify(node, null, 2))
for (const [key] of Object.entries(node)) {
inspectRecursively(node[key]);
}
}
handleString.js
function handleString(node) {
console.log(node)
}
handleNumber.js
function handleNumber(node) {
console.log(node.toString().padStart("0", 3))
}
Now I end up with a circular dependency.
main -> inspectRecursively -> handleObject -> importRecursively
I think this is bad, but am not sure about it?
What do I do in this situation? Do I change something to avoid the circular dependency?
I think this is bad, but am not sure about it?
No, it's not bad. ES6 modules do handle circular dependencies like this totally fine. Just make sure that all of these modules are pure and only contain function declarations, not top-level code that constructs values that depend on imported values: declarations are "hoisted" across modules.
Do I change something to avoid the circular dependency?
You could, by using explicit dependency injection:
// inspectRecursively.js
import { makeHandleObject } from "./handleObject.js"
import { handleString} from "./handleString.js"
import { handleNumber} from "./handleNumber.js"
const handleObject = makeHandleObject(inspectRecursively);
function inspectRecursively(node) {
…
}
// handleObject.js
export function makeHandleObject(inspectRecursively) {
return function handleObject(node) {
…
};
}
I would write Inspect as its own module -
// Inspect.js
const inspect = v =>
// ...
const handleString = e =>
// ...
const handleObject = e =>
// ...
const handleNumber = e =>
// ...
export { inspect } // only export functions the user should call
I don't really see the purpose of breaking each handle* into its own file.
Now when you use it in your program -
import { inspect } from './Inspect'
inspect(someObj) // => ...
I am new in the Aurelia community and it was given to me a task to make an entire upgrade of my current platform. (more info at the bottom).
Current problem:
Every time i redirect to the logout.js model a message is prompt
ERROR [app-router] TypeError: "this.view is null"
Questions:
How does a custom component "if-permission" can influence on non-view model?
Conlusions:
- I started to believe that any of the big files bellow are influencing the error at all! After commenting most of the code the error what still showing!
- Removed the noView() logic and added an empty logout.html! Guess what? Works like a charm! The logout will redirect to the login page.
This is my RouteConfig.js
{
route: 'logout',
viewPorts: {
main: {
moduleId: PLATFORM.moduleName('pages/logout/logout')
}
},
nav: false,
sidebar: false,
auth: false,
title: 'Logout',
name: 'logout',
}
This is my logout.js
import { noView } from 'aurelia-framework';
import authService from 'services/authService';
import uiService from 'services/uiService';
#noView()
export class LogoutPage {
activate() {
//THE ERROR PROMPTS EVEN WITH THE ABOVE LINES COMMENTED
uiService.impersonate(null, false);
authService.logout();
}
}
After searching a while i noticed that "this.view" is declared on this 2 files:
if-permission.js
import { inject, customAttribute, templateController, BoundViewFactory, ViewSlot } from 'aurelia-framework';
import userService from 'services/api/userService';
#customAttribute('if-permission')
#inject(BoundViewFactory, ViewSlot)
#templateController
export class IfPermission {
constructor(viewFactory, viewSlot) {
this.viewFactory = viewFactory;
this.viewSlot = viewSlot;
this.showing = false;
this.view = null;
this.bindingContext = null;
this.overrideContext = null;
}
/**
* Binds the if to the binding context and override context
* #param bindingContext The binding context
* #param overrideContext An override context for binding.
*/
bind(bindingContext, overrideContext) {
// Store parent bindingContext, so we can pass it down
this.bindingContext = bindingContext;
this.overrideContext = overrideContext;
this.valueChanged(this.value);
}
valueChanged(newValue) {
if (this.__queuedChanges) {
this.__queuedChanges.push(newValue);
return;
}
let maybePromise = this._runValueChanged(newValue);
if (maybePromise instanceof Promise) {
let queuedChanges = this.__queuedChanges = [];
let runQueuedChanges = () => {
if (!queuedChanges.length) {
this.__queuedChanges = undefined;
return;
}
let nextPromise = this._runValueChanged(queuedChanges.shift()) || Promise.resolve();
nextPromise.then(runQueuedChanges);
};
maybePromise.then(runQueuedChanges);
}
}
_runValueChanged(newValue) {
newValue = userService.hasPermission(newValue);
if (!newValue) {
let viewOrPromise;
if (this.view !== null && this.showing) {
viewOrPromise = this.viewSlot.remove(this.view);
if (viewOrPromise instanceof Promise) {
viewOrPromise.then(() => this.view.unbind());
} else {
this.view.unbind();
}
}
this.showing = false;
return viewOrPromise;
}
if (this.view === null) {
this.view = this.viewFactory.create();
}
if (!this.view.isBound) {
this.view.bind(this.bindingContext, this.overrideContext);
}
if (!this.showing) {
this.showing = true;
return this.viewSlot.add(this.view);
}
}
/**
* Unbinds the if
*/
unbind() {
if (this.view === null) {
return;
}
this.view.unbind();
if (!this.viewFactory.isCaching) {
return;
}
if (this.showing) {
this.showing = false;
this.viewSlot.remove(this.view, true, true);
}
this.view.returnToCache();
this.view = null;
}
}
if-user-role.js
import { inject, customAttribute, templateController, BoundViewFactory, ViewSlot } from 'aurelia-framework';
import userService from 'services/api/userService';
#customAttribute('if-user-role')
#inject(BoundViewFactory, ViewSlot)
#templateController
export class IfUserRole {
constructor(viewFactory, viewSlot) {
this.viewFactory = viewFactory;
this.viewSlot = viewSlot;
this.showing = false;
this.view = null;
this.bindingContext = null;
this.overrideContext = null;
}
/**
* Binds the if to the binding context and override context
* #param bindingContext The binding context
* #param overrideContext An override context for binding.
*/
bind(bindingContext, overrideContext) {
// Store parent bindingContext, so we can pass it down
this.bindingContext = bindingContext;
this.overrideContext = overrideContext;
this.valueChanged(this.value);
}
valueChanged(newValue) {
if (this.__queuedChanges) {
this.__queuedChanges.push(newValue);
return;
}
let maybePromise = this._runValueChanged(newValue);
if (maybePromise instanceof Promise) {
let queuedChanges = this.__queuedChanges = [];
let runQueuedChanges = () => {
if (!queuedChanges.length) {
this.__queuedChanges = undefined;
return;
}
let nextPromise = this._runValueChanged(queuedChanges.shift()) || Promise.resolve();
nextPromise.then(runQueuedChanges);
};
maybePromise.then(runQueuedChanges);
}
}
_runValueChanged(newValue) {
newValue = userService.hasRole(newValue);
if (!newValue) {
let viewOrPromise;
if (this.view !== null && this.showing) {
viewOrPromise = this.viewSlot.remove(this.view);
if (viewOrPromise instanceof Promise) {
viewOrPromise.then(() => this.view.unbind());
} else {
this.view.unbind();
}
}
this.showing = false;
return viewOrPromise;
}
if (this.view === null) {
this.view = this.viewFactory.create();
}
if (!this.view.isBound) {
this.view.bind(this.bindingContext, this.overrideContext);
}
if (!this.showing) {
this.showing = true;
return this.viewSlot.add(this.view);
}
}
/**
* Unbinds the if
*/
unbind() {
if (this.view === null) {
return;
}
this.view.unbind();
if (!this.viewFactory.isCaching) {
return;
}
if (this.showing) {
this.showing = false;
this.viewSlot.remove(this.view, true, true);
}
this.view.returnToCache();
this.view = null;
}
}
With this update i have integrated Aurelia-cli, updated aurelia-webpack and all the dependencies. Which made me switch some code like:
Add PLATFORM.moduleName() to all my platform
Add Require to all modules that were only getting components via < compose >
How to some actions data to many stores?
For example, I got some post data from server in user action.
So this is simple psudo action code.
class UserActions {
getPosts() {
asyncFetch(apiEndPoint, function(data) {
/*
* data : {
* PostStore : [ ... ],
* UserStore : { ... },
* CommentStore : [ ... ],
* AppDataStore : { ... },
* StatusDataStore : { ... },
* ...
* }
*
*/
PostActions.receiveStoreData(data.PostStore);
UserActions.receiveStoreData(data.UserStore);
CommentActions.receiveStoreData(data.CommentStore);
AppDataActions.receiveStoreData(data.AppDataStore);
StatusActions.receiveStoreData(data.StatusDataStore);
...
}
}
}
I'm curious about setting many store data into the each stores calling actions in the action.
How to fix it with best practice?
Your action creator should use the dispatcher to dispatch the corresponding action as below:
import { Dispatcher } from 'flux';
class UserActions {
getPosts() {
asyncFetch(apiEndPoint, function(data) {
const action = {
type: 'ADD_POSTS',
data
};
Dispatcher.dispatch(action);
}
}
// ...
}
Then one or more store can register to the dispatcher and listen to the same ADD_POSTS action:
import { EventEmitter } from 'events';
let posts = [];
const PostStore = Object.assign({}, EventEmitter.prototype, {
dispatcherIndex: AppDispatcher.register(action => {
const { type, data } = action;
switch (type) {
case 'ADD_POSTS':
posts = posts.concat(data);
PostStore.emitChange();
break;
// ...
}
return true;
});
emitChange() {
this.emit('change');
}
// ...
});