Is it possible to extend the Auth Service and add additional parameters to it?
Currently trying to extend but encounter error such as below:
ERROR in src/app/service/auth/auth-extend.service.ts(15,3): error TS2416: Property 'authorize' in type 'AuthExtendService' is not assignable to the same property in base type 'AuthService'.
Type '(userId: string, password: string, countryCode: string, businessType: string) => void' is not assignable to type '(userId: string, password: string) => void'.
src/app/service/auth/auth-extend.service.ts(21,7): error TS2345: Argument of type '{ userId: string; password: string; countryCode: string; businessType: string; }' is not assignable to parameter of type '{ userId: string; password: string; countryCode: string; businessType: string; }'.
Object literal may only specify known properties, but 'businessType' does not exist in type '{ userId: string; password: string; countryCode: string; businessType: string; }'. Did you mean to write 'businessType'? "
Any one here to tries to do this, like adding new parameters.
Typescript does not support such an overloading out of the box. One way of doing it would be by using optional parameters such as:
export class AuthExtendService extends AuthService {
authorize(userId: string, password: string, businessType?: string): void {
console.log(businessType);
this.store.dispatch(
new AuthActions.LoadUserToken({
userId: userId,
password: password,
})
);
}
}
This is how you should add extra parameters.
Related
I have the state like, I don't want to touch the rest of the state but specific property of an object in the state.
export interface User {
name: string;
email: string;
userGroup: string;
notification: boolean;
}
export interface SettingState {
user: User | null,
logs: any[],
trail: any[],
}
I want to update the user notification. Can I use patch for that purpose. I tried following but getting error.
patchNotfication(value: boolean) {
this.patchState({ user.notification: value})
}
and this code snippet gives another error
patchNotfication(value: boolean) {
this.patchState((state) => ({
user: value
}));
}
I get following error
What method would serve me best here?
I'm building a Converter to convert my DataObjects to ModelObjects and vice versa. I currently have two functions to do the converting. One for each conversion.
Currently, both of my conversion functions do exactly the same thing with exceptions to the type it takes and the type it returns. I was hoping I could write a generic function that would be able to handle both conversions because, otherwise, the code is exactly the same.
Here's what I've got: Obviously these are simplified examples
I've built a Protocol that contains the requirements for properties and an init(). I've implemented this Protocol and its init() in both the DataObject and ModelObject.
My Protocol:
protocol MyProtocol {
var id: UUID { get }
var name: String? { get }
init(id: UUID, name: String?)
}
My DataObject:
class DataObject: Object, MyProtocol {
#Persisted(primaryKey: true) var id: UUID
#Persisted var name: String?
required convenience init(id: UUID, name: String?) {
self.init()
self.id = id
self.name = name
}
}
My ModelObject:
struct ModelObject: MyProtocol {
var id: UUID
var name: String?
init(id: UUID, name: String?) {
self.id = id
self.name = name
}
}
Currently: This is an example what is currently doing the conversions. I have one like this for each conversion.
static func buildModelObject(object: DataObject) -> ModelObject {
let returnObject = ModelObject(id: object.id, name: object.name)
return returnObject
}
Desired Converter Function: I hope to accomplish something like this.
static func buildObject<O: MyProtocol, R: MyProtocol>(objectIn: O, returnType: R.Type) -> R {
let returnObject = returnType.init(id: objectIn.id, name: objectIn.name)
return returnObject
}
And I'm calling it like this:
let object = Converter.buildObject(objectIn: dataObject, returnType: ModelObject.self)
Obviously, this isn't working. Error: "Protocol 'MyProtocol' as a type cannot conform to the protocol itself". The error is on the function call. This is the only error XCode is showing me at compile.
I'm not certain what to do here or how to get it working. I'm not even confident that this error message is even helpful in any way.
The Question:
Is it even possible to accomplish something like this? If so, what am I missing? I'm still very unfamiliar with Swift Generics.
I don't have an issue with using multiple conversion functions as it's still better than getting the entire code base bogged down with Realm specific stuff. But, given that these functions are essentially the same, I'm hoping that Generics might be able to help reduce otherwise similar code into a single function.
Note: The DataObject is a Realm Object. I understand they have cool features like live/managed Objects. We're trying to keep our Persistence layer completely separated from the rest of the app with a single API/Entry Point. This is why I'm using these Converters.
You almost had it
func buildObject<R: MyProtocol>(objectIn: MyProtocol, returnType: R.Type) -> R {
let returnObject = returnType.init(id: objectIn.id, name: objectIn.name)
return returnObject
}
the key observation: at no point do we need the concrete type of objectIn, so just require the protocol type.
You don't need the other argument. The return type already provides the type information.
func buildObject<R: MyProtocol>(objectIn: some MyProtocol) -> R {
.init(id: objectIn.id, name: objectIn.name)
}
As suggested in the comments, this is more idiomatically expressed as an initializer.
extension MyProtocol {
init(_ objectIn: some MyProtocol) {
self.init(id: objectIn.id, name: objectIn.name)
}
}
can somebody explain why
class SaveGlove {
final String serialNumber;
final String productionDate;
SaveGlove(this.serialNumber, this.productionDate);
SaveGlove.fromJson(Map<String, Object?> json)
: this(
serialNumber: json['serialNumber']! as String,
productionDate: json['prductionDate']! as String,
);
Map<String, Object?> toJson() {
return {
'serialNumber': serialNumber,
'prductionDate': productionDate,
};
}
}
doesn't work but when I change parameter in constructor like that:
SaveGlove({required this.serialNumber, required this.productionDate});
it works?
Your original code doesn't work because your constructor is declared to take two positional arguments,
SaveGlove(this.serialNumber, this.productionDate);
but you are calling it with named arguments:
: this(
serialNumber: json['serialNumber']! as String,
productionDate: json['prductionDate']! as String,
);
(This is a redirecting generative constructor, which tries to redirect to the SaveGlove constructor by passing it two named arguments.)
That doesn't work, positional parameters need positional arguments.
If you had written the redirecting constructor as:
: this(
json['serialNumber']! as String,
json['prductionDate']! as String,
);
then it would have worked.
Changing the constructor to take two named parameters also makes the redirection be valid.
It is because Null Safety is added in Dart. In simple words, Null Safety means a variable cannot contain a ‘null’ value unless you initialized with null to that variable. All the runtime null-dereference errors will now be shown in compile time with null safety.
So as you are initializing variables serialNumber & productionDate you have two options:
Either make it compulsory to provide those variables values from constructor by adding required keyword.
class SaveGlove{
String serialNumber;
final String productionDate;
SaveGlove({required this.serialNumber, required this.productionDate});
}
Or declare those variables as nullable, i.e which can accept null values. So you don't need the required keyword:
class SaveGlove{
String? serialNumber;
String? productionDate;
SaveGlove({this.serialNumber,this.productionDate});
}
This is a strange one due to requirements of the project. Essentially I have struct conforming to Codable and CustomStringConvertible which I am using to decode JSON, however I am required to use the default implementation of description which I can't seem to do as description does not have a matching CodingKey and does not have a default value. Is there any way I can access the default value for description without using my own custom string? Example below
struct Source: CustomStringConvertible {
var description: String
var symbol: String
var line: Int
var image: String
var file: String
}
extension Source: Codable {
private enum CodingKeys : String, CodingKey {
case symbol
case line
case image
case file
}
}
you just need to change your description property declaration and make it a computed property instead:
var description: String { "Source - Symbol: \(symbol), Line: \(line), Image: \(image), File: \(file), " }
Note that there is no need to explicitly declare the coding keys:
struct Source: Codable {
let symbol, image, file: String
let line: Int
}
extension Source: CustomStringConvertible {
var description: String { "Source - Symbol: \(symbol), Line: \(line), Image: \(image), File: \(file), " }
}
I have the following code:
import { IsNotEmpty, IsArray, ArrayMinSize } from 'class-validator';
import { ApiProperty } from '#nestjs/swagger';
export class PublishDto {
#IsNotEmpty()
#IsArray()
#ArrayMinSize(1)
#ApiProperty({
type: [Product]
})
products: Product[];
}
interface Product {
id: string;
title: string;
sku: string;
stock: number;
description: string;
shortDescription: string;
imagesUrl: string[];
price: number;
department: string;
category: string;
brand: string;
keywords: string[];
isActive: boolean;
}
I'm trying to put the interface Product as a schema on swagger, but it's not working, I am getting an error.
Any idea?
The type property is expecting a value that is available at runtime, for example an actual Class or the Javascript String type. Interfaces exist only at compile time and so they aren't valid to be passed in this way.
You'll have to convert it to a Class if you want to pass it manually otherwise you could take a look at using the NestJS Swagger compiler plugin which uses some cool compile-time magic to automatically try and figure some of this stuff out for you