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

How can we import the entire Jasmine library using CucumberJS?

I am currently trying to implement unit testing using Jasmine and CucumberJS in my Angular v9 application. I have followed the tutorial provided by cucumber.io to set up cucumber as the default runner. However, I am facing difficulties in using Jasmine met ...

What is the most effective approach for annotating TypeScript abstract classes that are dynamically loaded?

I am in the process of developing a library that allows for the integration of external implementations, and I am exploring the optimal approach to defining types for these implementations. Illustration abstract class Creature { public abstract makeN ...

Retrieve user roles from core in Angular prior to implementing a guard

Hey, I'm facing an issue with my app.module setup. I have implemented lazy loading to load the core module and store roles in the core component. Everything works fine when I navigate from one page to another with the role guard applied. However, when ...

Angular2: The provided arguments do not correspond to any valid call signature

I have developed my own Observable service implementation import { Injectable, EventEmitter, Output} from '@angular/core'; @Injectable() export class CustomObservableService { data = []; @Output eventEmitter:EventEmitter = new EventEmit ...

Ionic 3 Storage Timing Explained

I have a scenario where I am trying to load JSON data from storage and display it on the HTML template of my page. However, when I try to do this, I encounter errors suggesting that the information is not yet available upon entering the page. I'm sta ...

Suddenly encountered issue when working with TypeScript Interfaces while integrating Quicktype 'allOf'

Our transition from using JSON Type Definition to JSON Schema includes the utilization of Quicktype to convert JSON Schemas into TypeScript Types. While Quicktype has been effective in most cases, it seems to struggle with converting Discriminators and mor ...

Importing BrowserAnimationsModule in the core module may lead to dysfunctional behavior

When restructuring a larger app, I divided it into modules such as feature modules, core module, and shared module. Utilizing Angular Material required me to import BrowserAnimationsModule, which I initially placed in the Shared Module. Everything function ...

Obtaining the accurate return type based on the generic parameter in a generic function

Is there a way to determine the correct return type of a function that depends on a generic argument? function f1<T>(o: T) { return { a: o } } // How can we set T to number through (n: number)? type T1 = typeof f1 extends (n: number) => infe ...

The address :::3000 is already in use by NestJS

While attempting to deploy my NestJs server on a C-Panel hosting, I have encountered an issue. Despite properly installing all node_modules and ensuring every project file is in place, the server fails to start and continuously displays the following error ...

Error TS2322: Type 'Partial<T>' is not assignable to type 'T'

I'm struggling to articulate my problem, so I think the best way to convey it is through a minimal example. Take a look below: type Result = { prop1: { val1: number, val2: string }, prop2: { val1: number } }; f ...

What is the best way to automatically log out a user when a different user logs in on the same browser?

Currently, I am encountering an issue where there are two separate dashboards for different types of users - one for admin and the other for a merchant. The problem arises when an admin logs in on one tab and then a merchant logs in on another tab in the s ...

Fairly intricate React function component declaration with TypeScript

const withAuth = () => <OriginalProps extends {}>( Component: React.ComponentType<OriginalProps & IAuthContextInterface> ) => { } (withAuth()(PrivateRoute)) // this is how the HOC called Could someone simplify what this function d ...

Guide on how to create a custom response using class-validator in NestJS

Is it feasible to customize the error response generated by class-validator in NestJs? The default error message structure in NestJS looks like this: { "statusCode": 400, "error": "Bad Request", "message": [ { "target": {} ...

The Karma tool is throwing a TypeError because it is unable to access the 'length' property of a null value

Despite reviewing numerous inquiries regarding this error, none have provided insight into identifying the root cause of the issue. How can I pinpoint the origin of this error and what steps can I take to resolve it? TypeError: Cannot read property ' ...

Display the dynamic change of minutes and seconds every second on an Ionic HTML page

I created a JavaScript countdown counter that displays minutes and seconds using the following line of code: document.getElementById("demo").innerHTML = Number(this.minutes) + 'm' + Number(this.seconds) + 's '; However, on iOS devices ...

The specified property cannot be found in the type 'IntrinsicAttributes & ...'

I'm currently working on adding a custom prop to a custom styled-component: interface Props { image?: string; title?: string; subtitle?: string; background?: string; } export function CardWide({ image, title, subtitle, background }: Props) ...

The object is not a valid function

Within this class object, I have an instance of a class that I am unable to call its functions within. Despite the IDE allowing me to call the getPoistionDiagram function: export class NodeW { childrenIds: string[]; diagram?: { coordinates: { ...

Using TypeScript with React Redux, encountering issue of property not being available in the Reducer from the ActionType

Currently, I am learning how to implement a Reducer in Redux while using React with TypeScript. I have encountered an issue that I need help with. Below are the action types that I am working with: import { LoginResponseInterface } from "../../interfaces ...

What are the counterparts of HasValue and .Value in TypeScript?

There is a method in my code: public cancelOperation(OperationId: string): Promise<void> { // some calls } I retrieve OperationId from another function: let operationId = GetOperationId() {} which returns a nullable OperationId, operat ...

Issues with concealing the side menu bar in Vue.js

I've been attempting to conceal the side menu bar, with the exception of the hamburger icon when in the "expanded" state. Despite my efforts to modify the CSS code, I am still struggling to hide the small side menu bar. The following images represent ...