When logging `self`, the output field is present; however, attempting to log `self.output` results in

I've encountered a strange issue. When I use console.log(self) to log the variable, it shows that the output key is set and contains all the values. However, if I try to log console.log(self.output), it returns undefined. Does anyone know why this is happening?

Below is my code snippet:

interface SearchOutput {
    total: 0,
    per_page: number,
    current_page: number,
    last_page: number,
    from: number,
    to: number,
    data: Array<Object>
}

interface SearchParams {
    query: string,
    perPage: number,
    index: string,
    type: string,
    page: number
}

export class Elastic {
    from: number;
    to: number;
    client: any;
    output: SearchOutput;
    error: any;

    constructor(host: string, log: string, elasticsearch: any) {
        this.client = new elasticsearch.Client({
            host: host,
            log: log
        })
    }

    public search({query, perPage, index, type, page}:SearchParams): SearchOutput {
        let self = this;
        this.client.search({
                'index': index,
                'type': type,
                'body': {
                    'query': {
                        'bool': {
                            'must': {
                                'query_string': {
                                    'query': query,
                                    'default_operator': 'AND',
                                    'fuzziness': 1
                                }
                            }, 'filter': []
                        }
                    }
                },
                'size': perPage,
                'from': 0
            },
            (err, response) => {
                const {hits, hits: {total}} = response
                const lastPage = Math.ceil(total / perPage)
                const from = (page * perPage) - perPage + 1
                const to = (page < lastPage) ? page * perPage : total
                let output = {
                    total: total,
                    per_page: perPage,
                    current_page: page,
                    last_page: lastPage,
                    from: from,
                    to: to,
                    data: []
                }
                if (total >= 1) {
                    for (const key in hits.hits) {
                        if (hits.hits.hasOwnProperty(key)) {
                            output.data.push(hits.hits[key]._source);
                        }
                    }
                } else {
                    output.data = [];
                }
                self.output = output;
            }
        );
        console.log(self); // outputs Elastic {client: EsApiClient, output:SearchOutput Objest with all values}
        console.log(self.output) // outputs undefined
        return self.output;
    }
}

Answer №1

Adjust your code to place the console.log inside the callback function:

this.client.search({
        'index': index,
        'type': type,
        'body': {
            'query': {
                'bool': {
                    'must': {
                        'query_string': {
                            'query': query,
                            'default_operator': 'AND',
                            'fuzziness': 1
                        }
                    }, 'filter': []
                }
            }
        },
        'size': perPage,
        'from': 0
    },
    (err, response) => {
        const {hits, hits: {total}} = response
        const lastPage = Math.ceil(total / perPage)
        const from = (page * perPage) - perPage + 1
        const to = (page < lastPage) ? page * perPage : total
        let output = {
            total: total,
            per_page: perPage,
            current_page: page,
            last_page: lastPage,
            from: from,
            to: to,
            data: []
        }
        if (total >= 1) {
            for (const key in hits.hits) {
                if (hits.hits.hasOwnProperty(key)) {
                    output.data.push(hits.hits[key]._source);
                }
            }
        } else {
            output.data = [];
        }
        self.output = output;
        console.log(self.output);
    }
);

UPDATE: One approach for managing asynchronous data retrieval and processing.

Your existing search method declaration:

public search({query, perPage, index, type, page}:SearchParams): SearchOutput

Revise it to

public search({query, perPage, index, type, page}:SearchParams, callback): SearchOutput

Now, upon receiving the data (within the method's callback), you can invoke the provided callback function:

if (total >= 1) {
    for (const key in hits.hits) {
        if (hits.hits.hasOwnProperty(key)) {
            output.data.push(hits.hits[key]._source);
        }
    }
} else {
    output.data = [];
}
callback(output) // invokes the passed-in callback method with the returned value

You may now call the search function as follows:

search(
    {'somequery', 'someperPage', 'someindex', 'sometype', 'somepage'}, 
    (data) => console.log(data)
)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Exploring Geofirestore's capabilities with advanced query functionalities

Thinking about updating my firestore collection structure to incorporate geoquery in my app. Geofirestore requires a specific structure: interface GeoDocument { g: string; l: GeoPoint; d: DocumentData; } I understand that geofirestore does ...

Injecting Dependencies with Angular 2 and the Ability to Include Optional Parameters

One issue I'm facing is that I have multiple components in my Angular 2 application that require the same dependency. This specific dependency needs a string for the constructor. How can I instruct angular2 to use a specific instance of this type for ...

How can you retrieve the property value from an object stored in a Set?

Consider this scenario: SomeItem represents the model for an object (which could be modeled as an interface in Typescript or as an imaginary item with the form of SomeItem in untyped land). Let's say we have a Set: mySet = new Set([{item: SomeItem, s ...

implementing dynamic visibility with ngIf directive in Angular

header.component.html <nav class="navbar navbar-default"> <div class="container-fluid"> <div class="navbar-header"> <a href="#" class="navbar-brand">Recipe Book</a> </div> <div class="collapse na ...

Creating a typescript type for contextual dispatch by leveraging the values of another interface

I am seeking to define a specific type for my "reducer" function. The "reducer" function I have takes in 2 parameters: the current state and the data sent in the dispatch context (to be used by the reducer). const reducer = ( state: any, props: { ...

Pausing in a NodeJS HTTP request listener until receiving another response before proceeding

Essentially, this is a web proxy. Within a request listener, I am creating another http request, reading its response, and passing it to the main response. But I have the challenge of needing to wait for the secondary request to complete before continuing. ...

What is the best way to set up a reactive form in Angular using the ngOnInit lifecycle

I have been facing an issue while trying to set up my reactive form with an observable that I subscribed to. Within the form class template, I used the ngOnInit lifecycle hook to fetch the desired object, which is the product. The first code snippet repre ...

Prevent ESLint from linting files with non-standard extensions

My .estintrc.yaml: parser: "@typescript-eslint/parser" parserOptions: sourceType: module project: tsconfig.json tsconfigRootDir: ./ env: es6: true browser: true node: true mocha: true plugins: - "@typescript-eslint" D ...

`Drizzle ORM and its versatile approach to SELECT statements`

Looking to improve the handling of options in a function that queries a database using Drizzle ORM. Currently, the function accepts options like enabled and limit, with potential for more options in the future. Here's the current implementation: type ...

Exploring Angular 4: Embracing the Power of Observables

I am currently working on a project that involves loading and selecting clients (not users, but more like customers). However, I have encountered an issue where I am unable to subscribe to the Observables being loaded in my component. Despite trying vario ...

How can union types be used correctly in a generic functional component when type 'U' is not assignable to type 'T'?

I've been researching this issue online and have found a few similar cases, but the concept of Generic convolution is causing confusion in each example. I have tried various solutions, with the most promising one being using Omit which I thought would ...

The error message "@graphql-eslint/eslint-plugin: problem with the "parserOptions.schema" configuration"

Our team is currently working on developing micro-services using NestJS with Typescript. Each of these services exposes a GraphQL schema, and to combine them into a single graph, we are utilizing a federation service built with NestJS as well. I recently ...

The TypeScript error message states, "The property 'breadcrumb' is not found within the type 'Data'."

My Breadcrumb Component is functioning properly when compiled to JavaScript and displaying the desired output. However, my IDE is showing an error message that I am struggling to fix. The error states: [ts] Property 'breadcrumb' does not exist o ...

Challenges with date formatting arise for Spanish speakers when the date returns as NaN or an Invalid

I have been working on an Angular app Objective: My aim is to allow users to input dates in Spanish format (DD/MM/YYYY) and display them as such, while converting them back to English format when saving the data to the Database. Issue: One problem I enco ...

Is it feasible to deduce the generic type of a function by considering all remaining arguments?

I'm working with code that looks like this: type Boxed<T> = { inner: T } const box = <T>(inner: T): Boxed<T> => ({ inner }); function test<T extends Boxed<any>>(...args: T[]): T extends Boxed<infer I> ? I : ne ...

The FOR UPDATE clause is not functioning as intended in the SELECT query

I have been working on isolating my database to prevent multiple servers from reading or updating data in the same row. In order to achieve this, I have structured my query like so: SELECT * FROM bridge_transaction_state as bridge WHERE bridge.state IN (&a ...

How can we ensure a generic async function with a return type that is also generic in Typescript?

I'm currently working on a function that retries an async function multiple times before rejecting. I want to make sure the typescript typings of the retry function are maintained and also ensure that the passed function is of type PromiseLike. Creat ...

Dealing with enum values in Jest tests when using Prisma can be tricky. The error message "Group[] not assignable to

Here is an example of my prisma postgresql schema: model User { id Int @id @default(autoincrement()) uuid String @db.Uuid createdat DateTime @default(now()) @db.Timestamp(6) updatedat DateTime @updatedAt first ...

Setting a callback function as a prop for react-paginate in TypeScript: A step-by-step guide

When using react-paginate, there is a prop called onPageChange with the following type: onPageChange?(selectedItem: { selected: number }): void; After implementing it like this: const onPageChange = (selected): void => { console.log(selected); } ...

What is the significance of TypeScript's dual generic typing feature?

defineListenerShape< EventName extends string, EventData extends { [key in EventName]: unknown; } > = <E extends EventName>(data: EventData[E]) => void; enum EventName { Click = 'click', Hover = 'hover' ...