Why are two classes in the same directory being imported differently in this Vue.js code? - vue.js

I'm working my way through the code of a Vue.js project.
In the file src/model/TextSegment.js the first two lines are:
import UniqueObject from "./UniqueObject";
import { TimeCode } from "#/model";
The file UniqueObject.js is a class file in the same directory, and so I understand that the ./ simply means the same directory and loads this file for use in TextSegment.js which extends this class.
But the file TimeCode.js is also a class in the same directory, albeit one that is instantiated, but I would expect it to be loaded with the same syntax, e.g.:
import TimeCode from "./TimeCode";
Why is TimeCode in squiggly brackets?
Why does it have a # instead of a . as a directory?
src/model/UniqueObject.js
import uuidv4 from "uuid/v4";
class UniqueObject {
constructor(initial = {}) {
if (this.constructor == UniqueObject) {
throw TypeError("Cannot instantiate abstract class UniqueObject");
}
this.uuid = initial.uuid || uuidv4();
}
}
export default UniqueObject;
src/model/TimeCode.js
class TimeCode {
constructor(initials = {}) {
this.seconds = initials.seconds || null;
this.frame = initials.frame || null;
}
}
export default TimeCode;
src/model/TextSegment.js
import UniqueObject from "./UniqueObject";
import { TimeCode } from "#/model";
class TextSegment extends UniqueObject {
constructor(initials = {}) {
super(initials);
this.content = initials.content || "";
this.translation = initials.translation || "";
this.notes = initials.notes || "";
this.timecode_start = new TimeCode(initials.timecode_start || {});
this.timecode_end = new TimeCode(initials.timecode_end || {});
this.voice_id = initials.voice_id || null;
this.filename = initials.filename || "";
}
}
export default TextSegment;

There are several ways of importing in JavaScript. These are the two most common ones.
import UniqueObject from "./UniqueObject"; imports the default export variable. If you open the UniqueObject file you would most likely see something like export default <var>.
import { TimeCode } from "#/model"; imports the TimeCode variable in the file at #/model. If you open the model file you would see something like export const TimeCode.
The # has to do with your module loader and depends on which module loader you use.

Related

How to leave existing class attribute on image element - now it is being moved to a generated enclosing span

Background: Trying to use ckeditor5 as a replacement for my homegrown editor in a non-invasive way - meaning without changing my edited content or its class definitions. Would like to have WYSIWYG in the editor. Using django_ckeditor_5 as a base with my own ckeditor5 build that includes ckedito5-inspector and my extraPlugins and custom CSS. This works nicely.
Problem: When I load the following HTML into ClassicEditor (edited textarea.value):
<p>Text with inline image: <img class="someclass" src="/media/uploads/some.jpeg"></p>
in the editor view area, browser-inspection of the DOM shows:
...
<p>Text with an inline image:
<span class="image-inline ck-widget someclass ck-widget_with-resizer" contenteditable="false">
<img src="/media/uploads/some.jpeg">
<div class="ck ck-reset_all ck-widget__resizer ck-hidden">
<div ...></div></span></p>
...
Because the "someclass" class has been removed from and moved to the enclosing class attributes, my stylesheets are not able to size this image element as they would appear before editing.
If, within the ckeditor5 view, I edit the element using the browser inspector 'by hand' and add back class="someclass" to the image, ckeditor5 displays my page as I'd expect it with "someclass" and with the editing frame/tools also there. Switching to source-editing and back shows the class="someclass" on the and keeps it there after switching back to document editing mode.
(To get all this, I enabled the GeneralHtmlSupport plugin in the editor config with all allowed per instructions, and that seems to work fine.) I also added the following simple plugin:
export default class Extend extends Plugin {
static get pluginName() {
return 'Extend';
}
#updateSchema() {
const schema = this.editor.model.schema;
schema.extend('imageInline', {
allowAttributes: ['class']
});
}
init() {
const editor = this.editor;
this.#updateSchema();
}
}
to extend the imageInline model hoping that would make the Image plugin keep this class attribute.
This is the part where I need some direction on how to proceed - what should be added/modified in the Image Plugin or in my Extend plugin to keep the class attribute with the element while editing - basically to fulfill the WYSIWYG desire?
The following version does not rely on GeneralHtmlSupport but creates an imageClassAttribute model element and uses that to convert only the image class attribute and place it on the imageInline model view widget element.
import Plugin from '#ckeditor/ckeditor5-core/src/plugin';
export default class Extend extends Plugin {
static get pluginName() {
return 'Extend';
}
#updateSchema() {
const schema = this.editor.model.schema;
schema.register( 'imageClassAttribute', {
isBlock: false,
isInline: false,
isObject: true,
isSelectable: false,
isContent: true,
allowWhere: 'imageInline',
});
schema.extend('imageInline', {
allowAttributes: ['imageClassAttribute' ]
});
}
init() {
const editor = this.editor;
this.#updateSchema();
this.#setupConversion();
}
#setupConversion() {
const editor = this.editor;
const t = editor.t;
const conversion = editor.conversion;
conversion.for( 'upcast' )
.attributeToAttribute({
view: 'class',
model: 'imageClassAttribute'
});
conversion.for( 'dataDowncast' )
.attributeToAttribute({
model: 'imageClassAttribute',
view: 'class'
});
conversion.for ( 'editingDowncast' ).add( // Custom conversion helper
dispatcher =>
dispatcher.on( 'attribute:imageClassAttribute:imageInline', (evt, data, { writer, consumable, mapper }) => {
if ( !consumable.consume(data.item, evt.name) ) {
return;
}
const imageContainer = mapper.toViewElement(data.item);
const imageElement = imageContainer.getChild(0);
if ( data.attributeNewValue !== null ) {
writer.setAttribute('class', data.attributeNewValue, imageElement);
} else {
writer.removeAttribute('class', imageElement);
}
})
);
}
}
Well, Mr. Nose Tothegrind found two solutions after digging through ckeditor5 code, here's the first one. This extension Plugin restores all image attributes that are collected by GeneralHtmlSupport. It can be imported and added to a custom ckeditor5 build app.js file by adding config.extraPlugins = [ Extend ]; before the editor.create(...) statement.
import Plugin from '#ckeditor/ckeditor5-core/src/plugin';
import GeneralHtmlSupport from '#ckeditor/ckeditor5-html-support/src/generalhtmlsupport';
export default class Extend extends Plugin {
static get pluginName() {
return 'Extend';
}
static get requires() {
return [ GeneralHtmlSupport ];
}
init() {
const editor = this.editor;
this.#setupConversion();
}
#setupConversion() {
const editor = this.editor;
const t = editor.t;
const conversion = editor.conversion;
conversion.for ( 'editingDowncast' ).add( // Custom conversion helper
dispatcher =>
dispatcher.on( 'attribute:htmlAttributes:imageInline', (evt, data, { writer, mapper }) => {
const imageContainer = mapper.toViewElement(data.item);
const imageElement = imageContainer.getChild(0);
if ( data.attributeNewValue !== null ) {
const newValue = data.attributeNewValue;
if ( newValue.classes ) {
writer.setAttribute('class', newValue.classes.join(' '), imageElement);
}
if ( newValue.attributes ) {
for (const name of Object.keys(newValue.attributes)) {
writer.setAttribute( name, newValue.attributes[name], imageElement);
}
}
} else {
writer.removeAttribute('class', imageElement);
}
})
);
}a
}

How to use pathlocationstrategy in angular 5 to set base href or APP_BASE_HREF?

Below is the code snippet:
import {
Router
} from "#angular/router";
import {
HttpClient
} from "#angular/common/http";
import {
environment
} from "../../environments/environment";
import {
Location,
LocationStrategy,
PathLocationStrategy
} from '#angular/common';
#Injectable()
export class CommonServicesService {
PathLocation: Location;
referralCode: any = localStorage.getItem('referenceCode');
constructor(
location: Location,
) {
this.PathLocation = location;
}
redirectAfterSuccessfulLogin() {
if (localStorage.getItem("redirectUrl")) {
let url = localStorage.getItem("redirectUrl");
localStorage.removeItem("redirectUrl");
this.PathLocation.prepareExternalUrl("'/'+this.referralCode"); //is this the correct way?
console.log(this.PathLocation);
this.router.navigate([url]);
} else {
this.PathLocation.prepareExternalUrl("'/'+this.referralCode");
console.log(this.PathLocation);
this.router.navigate(["/"]);
}
}
}
you can do some thing like that :
Create a baseUrl function that takes code as a parameter.
Call that function according to the condition after login,this will
gives you the updated URL
like this:
getBaseUrl = function(code){
return `localhost:3000/${code}`
}
now you can use it as :
getBaseURl(1234)
it returns : "localhost:3000/1234"
now you can add further path after this URL.
OR
you can further use same function for both the URL like this :
getBaseUrl = function(code){
if(code == 0000) return localhost:3000
else return `localhost:3000/${code}`
}
now whenever you are calling the function you have to pass 0000 for non-login condition Base Url and 4 digit code to get the after login base URL
getBaseURl(1234) // for login one
getBaseURl(0000) // for non-login one

ngx-chart error "TypeError: Object(...) is not a function"

I am trying to implements some statistics in my develepping platform and I try to use ngx-charts to display them. However I get an error and I can't figure out why.
I am using storedProcedures for MySQL statistics which I call from Java Restful Backend and return them in Angular 5 front-end. The returned table has the following two fields: Date and number of incidents per day. So the table returned by the backend has those two columns.
My code for the component rendering the chart is the following:
import {Component, OnInit} from '#angular/core';
import {StatisticsService} from '../../statistics.service';
class Data {
private _name: string;
private _value: number;
get name(): string {
return this._name;
}
set name(value: string) {
this._name = value;
}
get value(): number {
return this._value;
}
set value(value: number) {
this._value = value;
}
}
#Component({
selector: 'app-daily-incidents-statistics',
templateUrl: './daily-incidents-statistics.component.html',
styleUrls: ['./daily-incidents-statistics.component.css']
})
export class DailyIncidentsStatisticsComponent implements OnInit {
view: any[] = [700, 400];
data: any[] = [];
// options
showXAxis = true;
showYAxis = true;
gradient = false;
showLegend = false;
showXAxisLabel = true;
xAxisLabel = 'Ημέρα';
showYAxisLabel = true;
yAxisLabel = 'Αρ. Περιστατικών';
constructor(private statisticsService: StatisticsService) {
// Object.assign(this, { single })
// Object.assign(this, { data } );
}
colorScheme = {
domain: ['#5AA454', '#A10A28', '#C7B42C', '#AAAAAA']
};
onSelect(event) {
console.log(event);
}
async ngOnInit() {
console.log('NG ON INIT EXECUTION');
await this.getIncidentsByDay();
}
getIncidentsByDay() {
this.statisticsService.getIncidentsByDay()
.subscribe(
(results) => {
let temp = new Data();
for (let i in results) {
console.log(results[i][0] + '>>=====>> ' + results[i][1]);
temp.name = results[i][0];
temp.value = results[i][1];
this.data.push(temp);
}
const test = this.data;
// for (let i = 0; i < this.data.length; i++) {
// console.log('wtf: ' + this.data[i][0] + '::::' + this.data[i][1]);
// }
// console.log(results);
// console.log(JSON.stringify(results));
// Object.assign(this, {test});
}
);
}
}
However when I run the above code I get in JavaScript console the error:
ERROR TypeError: Object(...) is not a function
at BarVerticalComponent../src/common/base-chart.component.ts.BaseChartComponent.bindWindowResizeEvent (index.js:7818)
at BarVerticalComponent../src/common/base-chart.component.ts.BaseChartComponent.ngAfterViewInit (index.js:7730)
at callProviderLifecycles (core.js:12689)
at callElementProvidersLifecycles (core.js:12656)
at callLifecycleHooksChildrenFirst (core.js:12639)
at checkAndUpdateView (core.js:13794)
at callViewAction (core.js:14136)
at execComponentViewsAction (core.js:14068)
at checkAndUpdateView (core.js:13791)
at callViewAction (core.js:14136)
My Html Template File:
<div>
lalalal <br/>
ante pali... <br/>
kala ti na pw... <br/>
Gamiete pali... <br/>
<ngx-charts-bar-vertical
[view]="view"
[scheme]="colorScheme"
[results]="data"
[gradient]="gradient"
[xAxis]="showXAxis"
[yAxis]="showYAxis"
[legend]="showLegend"
[showXAxisLabel]="showXAxisLabel"
[showYAxisLabel]="showYAxisLabel"
[xAxisLabel]="xAxisLabel"
[yAxisLabel]="yAxisLabel"
(select)="onSelect($event)">
</ngx-charts-bar-vertical>
</div>
While the service for retreiving the values is:
import {Injectable} from '#angular/core';
import {HttpClient} from '#angular/common/http';
import {catchError} from 'rxjs/operators';
import {ErrorHandler} from '../shared/lib/error-handler';
import {Observable} from 'rxjs/Observable';
#Injectable()
export class StatisticsService {
constructor(private http: HttpClient) {
}
public getIncidentsByDay(): Observable<any> {
console.log("FEtching Incidents All By Day");
const url = 'statistics/incidents/day';
return this.http.get(url)
.pipe(catchError(ErrorHandler.handleError));
}
}
What am I doing wrong?
I am using Angular version 5.3 and ngx-charts 8.0 which is compatible with Angular 6 and not Angular 5. I installed ngx-charts version 7.4 and everything works fine.
I fixed the problem for me by downgrading to version 7.3.0
yarn add #swimlane/ngx-charts#7.3.0
I think I see the same with ngx-charts-bar-horizontal, whereas before this was not the case. The documentation page seems to be broken at the moment as well, so I assume the software has recently been updated in a broken way.
If you really need to use the 8.0 version, you can upgrade to angular 6 to solve the problem. Here is how you can do the upgrade from v5 to v6 https://stackoverflow.com/a/49474334
You can also think that the documention page is broken by now but ou can find it here https://swimlane.gitbook.io/ngx-charts/v/docs-test/installing

Call a Component method in Directive Angular 2

I have a directive which is supposed to call a method from component, but it fails doing this, what should be wrong ?
Here I will put the Directive, and a fragment of Component for understanding the problem..
Directive
import { Directive, EventEmitter, HostListener, Input, OnInit, Output } from '#angular/core';
import { GridComponent } from '../components/grid/grid.component';
import { Cell } from '../cell';
import { KEY_CODE } from '../keyCode.enum';
#Directive({
selector: '[appControl]',
})
export class GridDirective {
constructor(public gridComponent: GridComponent) {}
#HostListener('window:keydown', ['$event'])
handleKeyDown(event: KeyboardEvent) {
console.log(event.key);
const ITEMS = JSON.parse(localStorage.getItem('Grid'));
let key;
switch (event.key) {
case 'ArrowLeft': key = KEY_CODE.LEFT_ARROW;
break;
case 'ArrowUp': key = KEY_CODE.UP_ARROW;
break;
case 'ArrowRight': key = KEY_CODE.RIGHT_ARROW;
break;
case 'ArrowDown': key = KEY_CODE.DOWN_ARROW;
break;
}
this.gridComponent.move(ITEMS, key);
}
}
And here's the component method which it is supposed to call
move(array: Cell[][], key: KEY_CODE) {
localStorage.setItem('lastMove', JSON.stringify(key));
const DATA = this.gridService.move(array, this.score, key);
array = DATA.dataSheet;
this.score = DATA.rating;
this.best = this.gridService.scoreSender(this.score, this.best);
localStorage.setItem('Grid', JSON.stringify(array));
}
it's a wrong way to use a component as a service,
you should pass the "this" value from html and then assign it to gridComponent variable and for passing parameter to directive you can use input decorator
gridComponent :GridComponent;
#Input('appControl') set setGridComponent(gridComponent) {
this.gridComponent = gridComponent;
}
/// in html use property binding to pass the value to it
[appControl]="this"

mithril requires 'mithril' to be imported

I am writing a simple Mithril component, given below is the code
var m = require("mithril")
var MyComponent = {
view() {
return <button>Hello world!</button>;
}
};
export default MyComponent;
My problem is that in this scenario I am not using m as required, however when I remove this the app does not run, I get the following error
Uncaught ReferenceError: m is not defined(…)
It complains when you remove the m = require("mithril") line because when the JSX is transformed it becomes invocations of m().
var m = require("mithril")
var MyComponent = {
view() {
return <button>Hello world!</button>;
}
};
export default MyComponent;
becomes
var m = require("mithril");
var MyComponent = {
view: function view() {
return m(
"button",
null,
"Hello world!"
);
}
};
exports.default = MyComponent;
You can see the JSX transform live on the babel REPL