Localstorage.setItem() doesn´t work properly - validation

I have the following validator where I check if the usernamecontains admin in it, then I want to set the role to localStorage for later use and return isAdmin: true.
For some reason most of the times doesn´t write anything to localStorage, and then it does ocassionally which is weird.
Any idea what can be wrong?
import { FormControl } from "#angular/forms";
export class AdminValidator {
static getAdminValidator() {
return function adminValidator(control: FormControl): { [s: string]: boolean } {
// Write code here..
if (control.value.match(/^admin/)) {
localStorage.setItem('role', 'admin');
return { isAdmin: true };
}
return null;
}
}
}

Related

Return EventEmitter as Observable in Nest.js

EventEmitter in Nestjs is wrapper around EventEmitter2 module. I whant that Server-Sent Events return Observable with EE.
import { Controller, Post, Body, Sse } from '#nestjs/common';
import { fromEvent } from 'rxjs';
import { EventEmitter2 } from '#nestjs/event-emitter';
import { OrdersService } from './orders.service';
import { CreateOrderDto } from './dto/create-order.dto';
#Controller('orders')
export class OrdersController {
constructor(private ordersService: OrdersService,
private eventEmitter2: EventEmitter2) {}
#Post()
createOrder(#Body() createOrderDto: CreateOrderDto) {
// save `Order` in Mongo
const newOrder = this.ordersService.save(createOrderDto);
// emit event with new order
this.eventEmitter2.emit('order.created', newOrder);
return newOrder;
}
#Sse('newOrders')
listenToTheNewOrders() {
// return Observable from EventEmitter2
return fromEvent(this.eventEmitter2, 'order.created');
}
}
But after subscribtion to this source from browser i've getting only errors
this.eventSource = new EventSource('http://localhost:3000/api/v1/orders/newOrders');
this.eventSource.addEventListener('open', (o) => {
console.log("The connection has been established.");
});
this.eventSource.addEventListener('error', (e) => {
console.log("Some erorro has happened");
console.log(e);
});
this.eventSource.addEventListener('message', (m) => {
const newOder = JSON.parse(m.data);
console.log(newOder);
});
It's quite likely that you forgot to format the event in the right way.
For SSE to work internally, each chunk needs to be a string of such format: data: <your_message>\n\n - whitespaces do matter here. See MDN reference.
With Nest.js, you don't need to create such message manually - you just need to return a JSON in the right structure.
So in your example:
#Sse('newOrders')
listenToTheNewOrders() {
// return Observable from EventEmitter2
return fromEvent(this.eventEmitter2, 'order.created');
}
would have to be adjusted to, for example:
#Sse('newOrders')
listenToTheNewOrders() {
// return Observable from EventEmitter2
return fromEvent(this.eventEmitter2, 'order.created')
.pipe(map((_) => ({ data: { newOrder } })));
}
the structure { data: { newOrder } } is key here. This will be later translated by Nest.js to earlier mentioned data: ${newOrder}\n\n

Object still frozen when using Immer and NGXS

I am implementing ngxs into an existing codebase.
I have imported Immer and then ngxs bridge in hopes to handle side effects easier.
I've followed every example that I can find through google, I always get:
core.js:6014 ERROR TypeError: Cannot assign to read only property 'savedPrograms' of object '[object Object]'
I've tried using the #ImmutableContext() decorator to accont for this, but I get the exact same error. I also tried using the produce method, but when i give draft.savedPrograms a new value, it throws the error above.
#Action(UserActions.AddProgram)
#ImmutableContext()
public addProgram(ctx: StateContext<UserStateModel>, action) {
ctx.setState(
produce((draft: UserStateModel) => {
draft.user.savedPrograms = action.payload;
})
);
}
The only way i can get this to work is if i use JSON parse/stringify to create a copy of the user and then update the user object.
#Action(UserActions.AddProgram)
public addProgram(ctx: StateContext<UserStateModel>, action) {
const state = produce(draft => {
const copy = JSON.parse(JSON.stringify(draft));
copy.user.savedPrograms.push(action.payload);
draft = copy;
});
ctx.setState(state);
}
I'm not quite sure why ImmutableContext doesn't work out of the box
From immer-adapter documentation:
import { ImmutableContext, ImmutableSelector } from '#ngxs-labs/immer-adapter';
#State<AnimalsStateModel>({
name: 'animals',
defaults: {
zebra: {
food: [],
name: 'zebra'
},
panda: {
food: [],
name: 'panda'
}
}
})
export class AnimalState {
#Selector()
#ImmutableSelector()
public static zebraFood(state: AnimalsStateModel): string[] {
return state.zebra.food.reverse();
}
#Action(Add)
#ImmutableContext()
public add({ setState }: StateContext<AnimalsStateModel>, { payload }: Add): void {
setState((state: AnimalsStateModel) => ({
state.zebra.food.push(payload);
return state;
}));
}
}
As I understand you need to remove produce from your code:
#Action(UserActions.AddProgram)
#ImmutableContext()
public addProgram(ctx: StateContext<UserStateModel>, action) {
ctx.setState(
(draft: UserStateModel) => {
draft.user.savedPrograms = action.payload;
return draft;
}
);
}

How to change field size in Infor EAM?

How to change the size of fields in Infor EAM?
Anyone with experience with Infor EAM would be gladly appreciated.
You could do it using Extensible Framework. For example, following code will change width of work order and equipment description fields if you put it in EF of WSJOBS screen.
Ext.define(
'EAM.custom.external_WSJOBS', {
extend: 'EAM.custom.AbstractExtensibleFramework',
getSelectors: function () {
if( EAM.app.designerMode == false) {
return {
'[extensibleFramework] [tabName=HDR][isTabView=true]': {
afterlayout: function() {
try {
document.getElementsByName( 'description')[0].style.width = '700px';
document.getElementsByName( 'equipmentdesc')[0].style.width = '700px';
return true;
} catch( err) {
return true;
}
}
}
}
}
}
}
);

How to call the function inside other function both defined in same export default?

My code are:-
function showData(data) {
return {
type: 'SHOWDATA',
data,
};
}
export default {
fetchData() {
return function (dispatch) {
getDataApi.getData().then((response)=>dispatch(showData(response)).catch()
};},
updateData{
return function (dispatch) {
getDataApi.getData().then((response)=>if(response.isSucess)
{dispatch(fetchData())}).catch()
};}
}
After update call of the action I want to refresh the list thats why I
called dispatch(fetchData()); but it is showing that fetchData not
defined.How can I call the method defined in same export default function.
Can this help you? Not really exported as default but its named.
export const Actions = {
getAll,
add,
update,
view,
search
}
function getAll(){
return dispatch => {
dispatch(request());
Service.getAll()
.then(
response => {
// todo...
},
error => {
// catch error
}
);
}
function request() { return { type: Constants.LIST_REQUEST } }
function success(data) { return { type: Constants.LIST_SUCCESS, data } }
function failure(error) { return { type: Constants.LIST_FAILURE, error } }
}
function add(data){
return dispatch => {
dispatch(request());
Service.add(data)
.then(
response => {
if(response.status === 'fail'){
// do something
}else{
dispatch(success(response));
dispatch(getAll());
}
},
error => {
// do something
}
);
}
function request() { return { type: Constants.ADD_REQUEST } }
function success(data) { return { type: Constants.ADD_SUCCESS, data } }
function failure(error) { return { type: Constants.ADD_FAILURE, error } }
}

Backbone.js Model validate method

How can I validate only certain attributes on a model? Currently I check if the attribute exists in the object passed into validate:
validate: function(attrs) {
// Number
if (attrs.minimum) {
if (isNaN(attrs.minimum)) {
return -1;
}
}
if (attrs.maximum) {
if (isNaN(attrs.maximum)) {
return -1;
}
}
}
but if I want to validate string value then:
if (attrs.mystring) {
// Do validation
}
would fail and the validation never takes place.
Backbone now supports the has property. So you can do something like that:
var Person = Backbone.Model.extend({
defaults: {
"name": "Kevin",
"age" : 26,
"job" : "web"
},
validate: function(attrs, options) {
for(k in attrs) {
if(!this.has(k)) {
return k + ' attribute is not exist';
}
}
}
});
var person = new Person;
person.on("invalid", function(model, error) {
console.log(error);
});
Im a little confused by your wording, but I think you want to check if its not an empty string first? and also work out the possibility that it is undefined..if so then this is what you'll want to do..
validate: function(attrs) {
// Number
if (attrs.minimum) {
if (isNaN(attrs.minimum)) {
return -1;
}
}
if (attrs.maximum) {
if (isNaN(attrs.maximum)) {
return -1;
}
}
if (typeof(attrs.mystring) != "undefined"){
if (!attrs.mystring){
return -1;
}
}
}
if you want to only validate one of your attributes, you should write your validate function to accommodate the options accordingly
validate: function(attrs, option) {
if (!option){
// Number
if (attrs.minimum) {
if (isNaN(attrs.minimum)) {
return -1;
}
}
if (attrs.maximum) {
if (isNaN(attrs.maximum)) {
return -1;
}
}
if (!attrs.mystring){
return -1;
}
}else{
switch(option){
case("string"):
if (!attrs.mystring){
return -1;
}
break;
case("number"):
// Number
if (attrs.minimum) {
if (isNaN(attrs.minimum)) {
return -1;
}
}
if (attrs.maximum) {
if (isNaN(attrs.maximum)) {
return -1;
}
}
break;
}
}
}
there are many ways to do this, this probably being the least efficient lol but using your example, it will do the job.
also, this isn't really a backbone.js problem per say...but general js

Resources