How to share same data among two same component called twice on the same html template - node.js

I have created a pagination component that I am using above and below a table.
Issue is they create different memory reference for each call.
and hence creating a contradicting view as below:-
Above Table
Below Table
As we can see the Data on the html is same and 8 number is showing active on both but the array hold by both components contains different data.
How can I mirror both the components and make sure they share same data?
any help would be great thanks!

If you move the data to a service, then both instances of the component can share the same instance of the service and hence share the same data.
Would that work for you?
Here is an example service I have that shares these two values between multiple components:
Service
import { Injectable } from '#angular/core';
#Injectable()
export class ProductParameterService {
showImage: boolean;
filterBy: string;
constructor() { }
}
The class that uses the service then gets and sets the property into the service.
Class that uses the service
get showImage(): boolean {
return this.productParameterService.showImage;
}
set showImage(value: boolean) {
this.productParameterService.showImage = value;
}

Related

How to send params of current request to the constructor of the service?

Update: I have fixed it by only supplying the pattern of the path of the collection, and creating a function that can parse the provided IDs and now the functions themselves create the collections when they are called upon and it also works with Typescript:)
Updated in the repository:
https://github.com/Darkbound/nestjs-firebase/tree/main/src/firebase
In the user service:
https://github.com/Darkbound/nestjs-firebase/blob/main/src/user/user.service.ts
In the purchase transactions service: https://github.com/Darkbound/nestjs-firebase/blob/main/src/user/modules/purchase-transaction/purchase-transaction.service.ts
In the purchase transactions controller: https://github.com/Darkbound/nestjs-firebase/blob/main/src/user/modules/purchase-transaction/purchase-transaction.controller.ts#L14
Now the functionality works out of the box, the service class simply needs to extend the FirebaseCollectionService and give it the pattern of the path to the collection and thats it!
https://github.com/Darkbound/nestjs-firebase I have uploaded it into a repository, you only need to add .env with the keys for firebase admin.
And the specific example: https://github.com/Darkbound/nestjs-firebase/blob/main/src/user/modules/purchase-transaction/purchase-transaction.service.ts
I have created a class that gives me the functionality to perform CRUD operations on firebase, so that I can just directly inherit from it for any of my CRUD resources, as the logic is again usually mostly the same. Just like Nestjs generator gives me all of the routes for it.
#Injectable()
export class UserService extends NestjsFirebase<User> {
constructor(#InjectFirebaseAdmin() firebase: FirebaseAdmin) {
super(firebase, "users");
// console.log(userId);
}
}
This works great, I can reuse that for any level 1 collection I have in firebase, however if I want to get into a nested collection on firebase, well thats a problem, because the path there needs to be dynamic and super(firebase, "this is no longer just users").
Say if I want to access the transactions of a user, so users/SomeUserIdXYZ/transactions, then the path is entirely dependent on the userId and is changing, therefor, I need to recreate the instance of the service (I simply need a new instance of the class), with a new path:
super(firebase, ["users", userId, "transactions"]
However with my still limited knowledge about Nestjs I know that everything in it basically is a Singleton and there is probably no way to do this? To get a new instance of the service, for every request that I have?
The solution that I can think of is, to handle that within my route functions, so if its a findTransactions:
#Get("users/:userId/transactions")
async findTransactions(#Param("userId") userId: string) {
return this.userService.findAll(`users/${userId}/transactions`);
}
And I am pretty sure that this will work, if I add a path argument to each of the functions, but this seems like coupling the Controller with what my Path in firebase should look like, instead I need to be able to give it just the params so that it can create its own path.
This is NestjsFirebase:
#Injectable()
class NestjsFirebase<T> {
constructor(#InjectFirebaseAdmin() private readonly firebase: FirebaseAdmin, private readonly collectionPath: string) {}
async findAll(userId: string): Promise<T> {
const db = new FirebaseCollectionService<T>(this.firebase, this.collectionPath);
return await db.findAll(userId);
}
}
export class FirebaseCollectionService<T> {
protected db: CollectionReference<T>;
constructor(firebase: FirebaseAdmin, collectionPath: string) {
super(firebase.db);
this.db = this.createCollectionPath(collectionPath);
}
public async findAll(id: string) {
... some logic to find all transactions ...
}
}

DDD : Business Logic which need infra layer access should be in application service layer, domain service or domain objects?

For an attribute which need to be validated, lets say for an entity we have country field as VO
This country field needs to be validated to be alpha-3 code as per some business logic required by domain expert.
NOTE:
*We need to persist this country data as it can have other values also and possible in future there can be addition, updating and deleting of the country persisted data.
This is just one example using country code which may rarely change, there can be other fields which needs to be validated from persistence like validating some quantity with wrt data in persistence and it won't be efficient to store them in memory or prefetching them all.
Another valid example can be user creation with unique and valid domain email check, which will need uniqueness check from persistence
*
Case 1.
Doing validation in application layer:
If we call repository countryRepo.getCountryByCountryAlpha3Code() in application layer and then if the value is correct and valid part of system we can then pass the createValidEntity() and if not then can throw the error directly in application layer use-case.
Issue:
This validation will be repeated in multiple use-case if same validation need to be checked in other use-cases if its application layer concern
Here the business logic is now a part of application service layer
Case 2
Validating the country code in its value object class or domain service in Domain Layer
Doing this will keep business logic inside domain layer and also won't violate DRY principle.
import { ValueObject } from '#shared/core/domain/ValueObject';
import { Result } from '#shared/core/Result';
import { Utils } from '#shared/utils/Utils';
interface CountryAlpha3CodeProps {
value: string;
}
export class CountryAlpha3Code extends ValueObject<CountryAlpha3CodeProps> {
// Case Insensitive String. Only printable ASCII allowed. (Non-printable characters like: Carriage returns, Tabs, Line breaks, etc are not allowed)
get value(): string {
return this.props.value;
}
private constructor(props: CountryAlpha3CodeProps) {
super(props);
}
public static create(value: string): Result<CountryAlpha3Code> {
return Result.ok<CountryAlpha3Code>(new CountryAlpha3Code({ value: value }));
}
}
Is it good to call the repository from inside domain layer (Service
or VO (not recommended) ) then dependency flow will change?
If we trigger event how to make it synchronous?
What are some better ways to solve this?
export default class UseCaseClass implements IUseCaseInterface {
constructor(private readonly _repo: IRepo, private readonly countryCodeRepo: ICountryCodeRepo) {}
async execute(request: dto): Promise<dtoResponse> {
const someOtherKeyorError = KeyEntity.create(request.someOtherDtoKey);
const countryOrError = CountryAlpha3Code.create(request.country);
const dtoResult = Result.combine([
someOtherKeyorError, countryOrError
]);
if (dtoResult.isFailure) {
return left(Result.fail<void>(dtoResult.error)) as dtoResponse;
}
try {
// -> Here we are just calling the repo
const isValidCountryCode = await this.countryCodeRepo.getCountryCodeByAlpha2Code(countryOrError.getValue()); // return boolean value
if (!isValidCountryCode) {
return left(new ValidCountryCodeError.CountryCodeNotValid(countryOrError.getValue())) as dtoResponse;
}
const dataOrError = MyEntity.create({...request,
key: someOtherKeyorError.city.getValue(),
country: countryOrError.getValue(),
});
const commandResult = await this._repo.save(dataOrError.getValue());
return right(Result.ok<any>(commandResult));
} catch (err: any) {
return left(new AppError.UnexpectedError(err)) as dtoResponse;
}
}
}
In above application layer,
this part of code :
const isValidCountryCode = await this.countryCodeRepo.getCountryCodeByAlpha2Code(countryOrError.getValue()); // return boolean value
if (!isValidCountryCode) {
return left(new ValidCountryCodeError.CountryCodeNotValid(countryOrError.getValue())) as dtoResponse;
}
it it right to call the countryCodeRepo and fetch result or this part should be moved to domain service and then check the validity of the countryCode VO?
UPDATE:
After exploring I found this article by Vladimir Khorikov which seems close to what I was looking, he is following
As per his thoughts some domain logic leakage is fine, but I feel it will still keep the value object validation in invalid state if some other use case call without knowing that persistence check is necessary for that particular VO/entity creation.
I am still confused for the right approach
In my opinion, the conversion from String to ValueObject does not belong to the Business Logic at all. The Business Logic has a public contract that is invoked from the outside (API layer or presentation layer maybe). The contract should already expect Value Objects, not raw strings. Therefore, whoever is calling the business logic has to figure out how to obtain those Value Objects.
Regarding the implementation of the Country Code value object, I would question if it is really necessary to load the country codes from the database. The list of country codes very rarely changes. The way I've solved this in the past is simply hardcoding the list of country codes inside the value object itself.
Sample code in pseudo-C#, but you should get the point:
public class CountryCode : ValueObject
{
// Static definitions to be used in code like:
// var myCountry = CountryCode.France;
public static readonly CountryCode France = new CountryCode("FRA");
public static readonly CountryCode China = new CountryCode("CHN");
[...]
public static AllCountries = new [] {
France, China, ...
}
public string ThreeLetterCode { get; }
private CountryCode(string threeLetterCountryCode)
{
ThreeLetterCode = threeLetterCountryCode;
}
public static CountryCode Parse(string code)
{
[...] handle nulls, empties, etc
var exists = AllCountries.FirstOrDefault(c=>c.ThreeLetterCode==code);
if(exists == null)
// throw error
return exists;
}
}
Following this approach, you can make a very useful and developer-friendly CountryCode value object. In my actual solution, I had both the 2 and 3-letter codes and display names in English only for logging purposes (for presentation purposes, the presentation layer can look up the translation based on the code).
If loading the country codes from the DB is valuable for your scenario, it's still very likely that the list changes very rarely, so you could for example load a static list in the value object itself at application start up and then refresh it periodically if the application runs for very long.

How to connect two different ViewModels in Kotlin AndroidStudio

I have two different View Models with their own fragments, and I want my arrayListB in ViewModelB have the same value of my arrayListA in ViewModelA.
I am sure this may help you to do that!
Architecture Components provides ViewModel helper class for the UI controller that is responsible for preparing data for the UI. ViewModel objects are automatically retained during configuration changes so that data they hold is immediately available to the next activity or fragment instance. For example, if you need to display a list of users in your app, make sure to assign responsibility to acquire and keep the list of users to a ViewModel, instead of an activity or fragment, as illustrated by the following sample code:
class MyViewModel : ViewModel() {
private val users: MutableLiveData<List<User>> by lazy {
MutableLiveData<List<User>>().also {
loadUsers()
}
}
fun getUsers(): LiveData<List<User>> {
return users
}
private fun loadUsers() {
// Do an asynchronous operation to fetch users.
}
}
for more information see this :
(https://developer.android.com/topic/libraries/architecture/viewmodel?msclkid=bf393d12ce9011eca291710e2d69c5af)

Spring-Content: Moving files from content store to another content store

What I want: I'd like to move content from one ContentStore (regular) to another ContentStore (e.g. an archive) with Spring-Content version 1.2.7.
What I did is this (and it does work at least with DefaultFilesystemStoreImpls):
Creating two ContentStores like this:
#Bean(name = "mytmpfsstore1")
public ContentStore<File, String> getFileContentStore1() {
FileSystemResourceLoader loader = new FileSystemResourceLoader(".\\tmpstore1");
PlacementService placementService = new PlacementServiceImpl();
return new DefaultFilesystemStoreImpl<File, String>(loader, placementService, new FileServiceImpl());
}
Moving content from one ContentStore to another like this:
Optional<File> fileEntity = filesRepo.findById(id);
if (fileEntity.isPresent()) {
Resource resource = regularContentStore.getResource(fileEntity.get());
archiveContentStore.setContent(fileEntity.get(), resource);
filesRepo.save(fileEntity.get());
if (resource instanceof DeletableResource) {
((DeletableResource) resource).delete();
}
}
Question: Is this the intended way of moving (/archiving) content with Spring-Content or is there a more elegant / more convenient / more intended way of moving/archiving files (especially from filesystem to S3 and back again)?
Spring Content doesn't provide any magic here. I try to keep the API fairly low-level and this use case, whilst valid, is a little too granular.
So, ultimately you have to build the "archiving" yourself and at the end of the day copy the content from one store to another as you are doing.
A couple of comments/pointers:
Not sure why you instantiated mytmpfsstore1 yourself. If you have file storage and s3 storage you can just make your storage interfaces extend FileSystemContentStore and S3ContentStore respectively and let the framework instantiate them for you; i.e.
public interface MyTmpFsStore extends FileSystemContentStore {}
public interface MyS3store extends S3ContentStore()
You can then wire these two beans into your 'archive' code. Assuming that is a controller, something like:
#RequestMapping(...) public void archive(MyTmpFsStore fsStore, S3ContentStore s3Store { ... }
where you do your copy operation.
ContentStore extends AssociativeStore and there are a few different APIs for setting/unsetting content. Resource-based or InputStream. They all achieve the same objective at the end of the day. You could just have easily used getContent instead of getResource and unsetContent instead of delete.
The 'archive' code probably needs to be in a #Transactional so the archive operation is atomic.

Dynamically referencing a Service using Felix annotations

I have created an interface which two different services are implementing.
Consider interface is named as CheckReference and two different classes CheckReferenceImpl1 and CheckReferencImpl2 are implementing it.
#Component
#Service(value = CheckReference.class)
#Property(name = "domain", value = "ref1")
public class CheckReferenceImpl1 implements CheckReference
And another one,
#Component
#Service(value = CheckReference.class)
#Property(name = "domain", value = "ref2")
public class CheckReferenceImpl2 implements CheckReference
Now I want to dynamically load the implementation depending on my need using #Reference annotation dynamically.
So , In a check condition
public class LoadReference {
#Reference
CheckReference checkReference
if(check) {
// load checkReferencImpl1
} else {
// load checkReferenceImpl2
}
}
Also I know that I can use target property to load specific implemenation. But that is static way.
But in order to do this dynamically , Not able to relate from specifications and tutorials how should I do this ??
First, you have to make LoadReference a #Component, so that it is managed by the SCR (otherwise #Reference won't work either). Next, you have to provide a configuration for it using the Configuration Admin Service. In this configuration, you can provide a filter for the reference by providing a property with the name REFERENCE_NAME.target:
checkReference.target = FILTER_EXPRESSION
FILTER_EXPRESSION is a standard LDAP-expression used in OSGi-filters. Due to property propagation, this configuration property will be propagated to the service-component, and it will be used when selecting a target service for checkReference. This does not require any code for checking the condition in LoadReference.
Have you looked at ComponentContext.locateService?

Resources