npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@cartona/ngx-catalog

v0.1.0

Published

This is an Angular-only client-side package (compatible with Angular > 15.0.0).

Downloads

35

Readme

Cartona Catalog Angular Client

This is an Angular-only client-side package (compatible with Angular > 15.0.0).

Your will need to have a running Cartona Catalog server you can connect to.

The current version is <1.0.0, meaning the project is still under development. It should not be used in production without close monitoring.

Further documentation is available from the developers upon request.

Installing the component

Install the component itself:

npm install @cartona/ngx-catalog

Embedding the component

If you only need to use the model and service classes, add nothing to your module files.

Make sure to have the following in the module file containing the components where you want to use the visual components:

import { CatalogUIModule } from '@cartona/ngx-catalog';
...
imports: [
    ...
    CatalogUIModule
]

Now you can embed the visual components in your html:

<catalog-recommender #rcmd 
        [server_url]="<your server base url>" 
        [token]="<token provided by server-side login - recommended>"
        [username]="<buyer or seller id>"
        >
</catalog-recommender>

<catalog-ui-search-box [recommender]="rcmd" 
        [phrase]="phrase"
        [debounce]="300"
        (onSearch)="search($event)"
        [class]="'test-search-box'">
</catalog-ui-search-box>
    
<catalog-ui-item-list [recommender]="rcmd">
</catalog-ui-item-list>

By binding a search box and an item list to a recommender, every search is automatically displayed. However, only a default view style is given which you can use for testing but need to replace with your own UI.

You can provide your own template for each item and a template to use when no items are available.

<catalog-ui-item-list [recommender]="rcmd">
    <ng-template let-item>
        <div class="test-card">
            <div class="title">
                {{ item?.name }}
            </div>
            <div class="flags" *ngIf="item.score">
                <span *ngIf="item.score.total">Score: {{ item.score.total }}</span>
                <span class="flag" *ngIf="item.score.globalSales > .2">Best Seller</span>
                <span class="flag" *ngIf="item.score.categoryLeaders > .2">Category Leader</span>
                <span class="flag" *ngIf="item.score.trendingItems > .2">Trending</span>
            </div>
        </div>
    </ng-template>
    <div noItems>
        <div class="test-card">No Items. Please try another search..</div>
    </div>
</catalog-ui-item-list>

You can also use the list component to display data other than items. Categories and Brands can also be shown. However, this offers no advantage over your own listing since you have to bind events yourself in the current version.

Passing options to the recommender component:

Options can be bound directly as a RecommenderOptions instance in the options attribute.

To separate configuration form page code, you can create a RecommenderProfile on the server and simply refer to it instead of passing options (in the profile attribute). When both attributes are provided, the given options override settings in the given profile.

An alternative would be to use the service provider directly and fetch items manually, binding them to your own UI components.

    listRelated(product: Product, options: RecommenderOptions) {
        this.service.recommendSimilarItems(product.id, options)
        .then(map => {
            this.similar = map?.get(product.id);
        });

        this.service.recommendBoughtTogether(product.id, options)
        .then(map => {
            this.together = map?.get(product.id);
        });
    }    

Using the service to call the API

Inject the CatalogService provider in your class.

Before calling any methods, set the url and token to authenticate requests.

The token should be obtained from your server (you need to provide your own endpoint). This allows server-to-server login which is secure and can be protected.

A token expires in 6 hours by default. This can be changed from the Catalog server configuration. Make sure to fetch a new token before the old one expires.

You can also call service.login(username) to fetch a token from the client side. This is not currently secure and is meant only as an aid to development. Login can be called multiple times without ill effects, since an existing token will not be overridden. To override/refresh a token call service.relogin(username).

    public login(username: string): Promise<string | undefined>

    public relogin(username: string): Promise<string | undefined>

    public setToken(token: string)

Use one of the methods provided to fetch categories, brands, sellers, buyers, or items by passing a query, a page size, and a page rank.

    public listProducts(query: string, pageSize: number, page?: number):
        Promise<ItemSubset<Product> | undefined>

    public listProductsByFeature(query: string, features: any, pageSize: number, page?: number):
        Promise<ItemSubset<Product> | undefined>

    public listLookups(type: string, pageSize: number, page?: number):
        Promise<ItemSubset<LookupItem> | undefined>

    public listFeatures(category?: string, brand?: string, expand?: boolean):
        Promise<any | undefined>

    public listSellerInput(seller?: Seller | string, product?: Product | string, expand?: string): 
        Promise<ItemSubset<SellerInput> | undefined>

You can also direct queries to ElasticSearch by using one of the search methods. These employ fuzzy text search against all known data. For more fine-tuning you can search any index (including custom indices) directly, specifying the fields to search, their weight, and any filters to apply.

    public searchProducts(query: string, pageSize: number, page?: number):
        Promise<ItemSubset<Product> | undefined>

    public searchSellers(query: string, pageSize: number, page?: number):
        Promise<ItemSubset<Seller> | undefined>
    
    public searchBuyers(query: string, pageSize: number, page?: number):
        Promise<ItemSubset<Buyer> | undefined>

    public searchProductsBySeller(query: string, seller: Seller | string, pageSize: number, page?: number):
            Promise<ItemSubset<Product> | undefined>

    public searchSellersByProduct(query: string, product: Product | string, pageSize: number, page?: number):
            Promise<ItemSubset<Seller> | undefined>

    public searchIndex(query: string, options: IndexSearchOptions, pageSize: number, page?: number): 
		Promise<ItemSubset<any> | undefined>

You can also use a recommendation method to fetch recommended items according to a mode or preset profile. You may need to pass one or more items or a query string according to the selected mode. In all cases, a RecommenderOptions instance is also required. Simply create a new instance and pass it of you want to rely on server-side configuration.

    public recommendPopularItems(options: RecommenderOptions):
        Promise<ScoredProduct[] | undefined>

    public recommendTrendingItems(options: RecommenderOptions):
        Promise<ScoredProduct[] | undefined>

    public recommendSearchItems(query: string, options: RecommenderOptions):
        Promise<ScoredProduct[] | undefined>

    public recommendSimilarItems(items: string | string[], options: RecommenderOptions):
        Promise<Map<string, ScoredProduct[]> | undefined>

    public recommendBoughtTogether(items: string | string[], options: RecommenderOptions):
        Promise<Map<string, ScoredProduct[]> | undefined>

    public recommendBySimilarBuyers(items: string | string[], options: RecommenderOptions):
        Promise<ScoredProduct[] | undefined>

    public recommendAddToCart(items: string | string[], options: RecommenderOptions):
        Promise<ScoredProduct[] | undefined>

    public recommendProfile(name: string, query: string | undefined, items: string | string[] | undefined, options: RecommenderOptions):
        Promise<Map<string, ScoredProduct[]> | undefined>

Generated documentation available at: https://cartona.github.io/survey-cp/ngx-catalog

Please always refer to the actual code, which provides inline help. This list may not always be up-to-date.