Jhipster webpack compilation error when checking an array value - arrays

I am using Jhipster with Angular. I have a method that is trying to check to see if the user in as admin.
import { Component, OnInit } from '#angular/core';
import { ActivatedRoute } from '#angular/router';
import { IPost } from 'app/shared/model/post.model';
import { AccountService } from 'app/core/auth/account.service';
import { Subscription } from 'rxjs';
import { Account } from 'app/core/user/account.model';
#Component({
selector: 'jhi-post-detail',
templateUrl: './post-detail.component.html'
})
export class PostDetailComponent implements OnInit {
post: IPost | null = null;
authSubscription!: Subscription;
account: Account | null = null;
constructor(protected activatedRoute: ActivatedRoute, private accountService: AccountService) { }
ngOnInit(): void {
this.activatedRoute.data.subscribe(({ post }) => (this.post = post));
this.authSubscription = this.accountService.getAuthenticationState().subscribe(account => (this.account = account));
}
previousState(): void {
window.history.back();
}
private isAdmin(): boolean | undefined {
return this.account?.authorities.includes('ROLE_ADMIN');
}
}
When the code is compiled I get an error
ERROR in ./src/main/webapp/app/entities/post/post-detail.component.ts 21:30
Module parse failed: Unexpected token (21:30)
File was processed with these loaders:
* ./node_modules/angular2-template-loader/index.js
* ./node_modules/cache-loader/dist/cjs.js
* ./node_modules/thread-loader/dist/cjs.js
* ./node_modules/ts-loader/index.js
* ./node_modules/eslint-loader/dist/cjs.js
You may need an additional loader to handle the result of these loaders.
| }
| isAdmin() {
> return this.account ? .authorities.includes('ROLE_ADMIN') : ;
| }
| };
ℹ 「wdm」: Failed to compile.
As a workaround, if I just hard-code the return value to 'true' in the isAdmin() method it works and compiles. How come just checking to see if the array contains something causes the webpack to freak out?

Optional chaining was introduced in Typescript 3.7, current JHipster 6.7.1 uses Typescript 3.4.5 so it's not very surprising that your expression is not understood and translated as ternary operator.
Try upgrading typescript version in package.json and npm install to see if it solves it.

Related

Jest, Enzyme, React, Next.js, Typescript .default is not a constructor

I want to write simple test checking if my next.js page loads without errors.
I followed this tutorial and I almost got it working, but simple-react-validator stays in my way with the following error when i run npm run test which justs run jest behind the scene:
TypeError: simple_react_validator_1.default is not a constructor
private validator : SimpleReactValidator = new SimpleReactValidator({
| ^
96 | locale: 'en',
97 | autoForceUpdate: this,
98 | validators: {
Before I couldn't even use simple-react-validator with my Typescript Next.js application. I needed to add to next-env.d.ts this:
declare module 'simple-react-validator' {
const content: any;
export default content;
}
Then I was able to use it in my application, but tests are complaining about constructor.
What can cause this issue? Maybe I need to somehow explicitly tell it somewhere what SimpleReactValidator is but I don't know where.
After some time I figured it out.
If using typescript, you must to wrap your mock in 'default' property:
jest.mock('simple-react-validator', () => {
return {
'default': class SimpleReactValidatorMock {
allValid() { return true; }
fieldValid() { return true; }
message() { return ''; }
}
}
});
I found the answer here:
https://github.com/kulshekhar/ts-jest/issues/120#issuecomment-283653644

jhipster react remove # to URL

I'm new to the community. I built an e-commercce application with the Jhipster (Java + React Redux) Monolitica. I have the following problem: The application is configured to display a hashtag (#) in the URL for example ... http://localhost:9000/#/. I removed this parameter in React and everything was right. But when I upload the application with Gradle (./gradew) it works, http://localhost:9000/. But if you type directly into the browser http://localhost:9000/home/ I get ERROR 404, Page not found! -----> my application to check the problem (http://www.severobalanceboard.eco.br - OK), (http://www.severobalanceboard.eco.br/historia - ERROR 404)
_
I think this problme by Spring.
Resolved, for remove Hash tag # To URL, using Jhipster and React [Spring + ReactJs]. I use the link of #Gaël Marziou told me.
follows the modifications:
==React==
1 - com/mycompany/myapp/src/main/webapp/app/app.tsx
import { BrowserRouter as Router } from 'react-router-dom';
// import { HashRouter as Router } from 'react-router-dom';
2 - com/mycompany/myapp/src/main/webapp/index.html
<!-- <base href="./"/> -->
<base href="/"/>
3 - com/mycompany/myapp/webpack/webpack.prod.js
},
devServer: {
historyApiFallback: true, /*insert this line - only use for develop*/
stats: options.stats,
hot: true,
contentBase: './build/www',
proxy: [{
context: [
...
==JAVA==
4 - com/mycompany/myapp/src/main/java/br/com/MyApp/config/WebConfigurer.java
#Bean
public Html5RouteFilter html5RouteFilter() {
return new Html5RouteFilter();
}
5 - com/mycompany/myapp/src/main/java/br/com/MyApp/web/Html5RouteFilter.java
YOU NEED CREATE THIS FILE
package com.mycompany.myapp.web;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.regex.Pattern;
/**
* Filter that distinguishes between client routes and server routes when you don't use '#' in client routes.
*/
public class Html5RouteFilter extends OncePerRequestFilter {
private Logger log = LoggerFactory.getLogger(getClass());
// These are the URIs that should be processed server-side
private static final Pattern PATTERN = Pattern.compile("^/((api|content|i18n|management|swagger-ui|swagger-resources)/|error|h2-console|swagger-resources|favicon\\.ico|v2/api-docs).*");
#Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {
if (isServerRoute(request)) {
filterChain.doFilter(request, response);
} else {
RequestDispatcher rd = request.getRequestDispatcher("/");
rd.forward(request, response);
}
}
protected static boolean isServerRoute(HttpServletRequest request) {
if (request.getMethod().equals("GET")) {
String uri = request.getRequestURI();
if (uri.startsWith("/app")) {
return true;
}
return PATTERN.matcher(uri).matches();
}
return true;
}
}
===END==
now be happy

Cannot use my own polyfill for React Native Object.assign

Due to this issue https://github.com/facebook/metro/commit/9773229227895bfc5a5bde969108a4cbcc270eab#diff-ce1179d24387784c3c5f856c4b5b55d8R59
Object.assign fails on dev builds for RN under certain scenarios (which is explained in the above link's comments). The issue is that one of my node modules triggers this particular scenario. I need to polyfill for that reason.
I'm trying to polyfill my own Object.assign (based on this https://github.com/facebook/react-native/blob/1151c096dab17e5d9a6ac05b61aacecd4305f3db/Libraries/polyfills/Object.es6.js, except without the check for an existing one)
When I log out global from within the node module, I can see that it is pointing to my code
Object: ƒ Object()
arguments: (...)
assign: ƒ assign(target, varArgs)
arguments: (...)
caller: (...)
length: 2
name: "assign"
prototype: {constructor: ƒ}
__proto__: ƒ ()
[[FunctionLocation]]: objectAssign-polyfill.js:2
[[Scopes]]: Scopes[1]
However, the node module still appears to be using its own Object.assign rather than my polyfilled one.
When I modify the code in the node module to use global.Object.assign, it seems to finally work. However, is there a way to do this without doing that (because then I'd have to do it everywhere)?
The code is below:
// objectAssign-polyfill.js
Object.defineProperty(Object, 'assign', {
value: function assign(target, varArgs) {
'use strict';
if (target == null) {
throw new TypeError('Cannot convert undefined or null to object');
}
let to = Object(target);
for (let index = 1; index < arguments.length; index++) {
let nextSource = arguments[index];
if (nextSource != null) {
for (let nextKey in nextSource) {
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
to[nextKey] = nextSource[nextKey];
}
}
}
}
return to;
},
writable: true,
configurable: true,
});
// shims.js
import "node-libs-react-native/globals";
import './objectAssign-polyfill'
import { btoa } from "Base64";
import nodeUrl from 'url';
global.btoa = btoa;
global.URL = class URL {
constructor(url) {
return nodeUrl.parse(url)
}
}
// index.js (the root of my RN app)
/** #format */
import "./shims";
import { AppRegistry } from "react-native";
import Core from "./Core";
import { name as appName } from "./app.json";
AppRegistry.registerComponent(appName, () => Core);

Importing json2csv module in Angular 4

I am trying to use this library in my application to convert JSON data to CSV file format. I installed the lib into my project as it mentions https://www.npmjs.com/package/json2csv
npm install json2csv --save.
I also see the module in my node_module folder. Then in my component class i am calling it like so
import { json2csv } from 'json2csv';
But then I get this error
[ts] Module '"c:/dev/angularworkspace/tntzweb/node_modules/json2csv/index"' has no exported member 'json2csv'.
Can someone please help me!!
Change the import to:
import * as json2csv from 'json2csv';
Then implement as:
let fields = ['field1', 'field2', 'field3'];
  let result = json2csv({ data:[{ field1: 'a', field2: 'b', field3: 'c' }], fields: fields });
  console.log(result);
The other answers are now outdated. For json2csv version 5, first:
npm install --save json2csv #types/json2csv
Then at the top of your Angular component/service/etc:
import { parse } from 'json2csv';
Then to generate the csv in your method:
const csv = parse(json);
There are, of course, all kinds of options you can pass to parse() and json2csv exposes other classes and functions you can import and use as well. There are useful examples in the tests from #types/json2csv.
Here is a complete CSV download implementation:
<a [download]="csvFileName" [href]="getCSVDownloadLink()">CSV export</a>
import { Component } from '#angular/core';
import { DomSanitizer } from '#angular/platform-browser';
import * as json2csv from 'json2csv';
#Component({
selector: 'csv-download',
templateUrl: './csv-download.component.html',
styleUrls: ['./csv-download.component.scss']
})
export class CsvDownloadComponent {
public csvFileName = `test.csv`;
private SOME_DATA: any[] = [{id: 1, name: 'Peter'}, {id: 2, name: 'Sarah'}];
constructor(
private domSanitizer: DomSanitizer,
) { }
getCSVDownloadLink() {
return this.generateCSVDownloadLink({
filename: this.csvFileName,
data: this.SOME_DATA,
columns: [
'id',
'name',
],
});
}
// you can move this method to a service
public generateCSVDownloadLink(options: { filename: string, data: any[], columns: string[] }): SafeUrl {
const fields = options.columns;
const opts = { fields, output: options.filename };
const csv = json2csv.parse(options.data, opts);
return this.domSanitizer.bypassSecurityTrustUrl('data:text/csv,' + encodeURIComponent(csv));
}
}
You can use the angular 2 version of the library. The link to the same is: https://github.com/aqeel-legalinc/angular2-json2csv

Typescript: AngularJS 1 constant issue

I am creating an app with TypeScript and AngularJS 1, and I have run into a problem with creating a constant and passing the constant to the other class. I have the following constant in my app:
module app{
export class AUTH_EVENTS {
static get Default():any {
return {
LOGIN_SUCCESS: 'AUTH_EVENTS:LOGIN_SUCCESS',
LOGIN_FAILED: 'AUTH_EVENTS:LOGIN_FAILED',
LOGOUT_SUCCESS: 'AUTH_EVENTS:LOGOUT_SUCCESS',
LOGOUT_FAILED: 'AUTH_EVENTS:LOGOUT_FAILED',
SESSION_TIMEOUT: 'AUTH_EVENTS:SESSION_TIMEOUT',
NOT_AUTHORIZED: 'AUTH_EVENTS:NOT_AUTHORIZED'
};
}
}
var app = getModule();
app.constant("AUTH_EVENTS", AUTH_EVENTS.Default())
}
Which I try to access here:
module app{
class auth{
constructor(public $q: ng.IQService,
public $state:angular.ui.IState,
public AUTH_EVENTS: AUTH_EVENTS){
}
responseError(response:any) {
if (response.status === 401) {
console.log(this.AUTH_EVENTS.LOGIN_SUCCESS);
}
return this.$q.reject(response);
}
}
}
The issue that I have, is that in
console.log(this.AUTH_EVENTS.LOGIN_SUCCESS)
the LOGIN_SUCCESS is not defined.
Do you have any ideas why is this happening? Is there any issue with defining the constant, or is it the issue with the class auth. To be more specific, this is the error that I get when I compile TS into JS:
error TS2339: Property 'LOGIN_SUCCESS' does not exist on type 'AUTH_EVENTS'.
What about this definiton:
module app{
export class AUTH_EVENTS {
LOGIN_SUCCESS= 'AUTH_EVENTS:LOGIN_SUCCESS';
LOGIN_FAILED= 'AUTH_EVENTS:LOGIN_FAILED';
LOGOUT_SUCCESS= 'AUTH_EVENTS:LOGOUT_SUCCESS';
LOGOUT_FAILED= 'AUTH_EVENTS:LOGOUT_FAILED';
SESSION_TIMEOUT= 'AUTH_EVENTS:SESSION_TIMEOUT';
NOT_AUTHORIZED= 'AUTH_EVENTS:NOT_AUTHORIZED';
static Default() { return new AUTH_EVENTS(); }
}
var app = getModule();
app.constant("AUTH_EVENTS", AUTH_EVENTS.Default())
}

Resources