What is the best way to retrieve variable data from a Node.js function in an external context?

This Node.js function is designed to retrieve data from Analytics:

function getDataFromGA(Dimension, Metric, StartDate, EndDate, MaxResults) {
var fs = require('fs'),
    crypto = require('crypto'),
    request = require('request'); // This module is external 

var authHeader = {
        'alg': 'RS256',
        'typ': 'JWT'
    },
    authClaimSet = {
        'iss': '***<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b0c4f0d4d5c6d5dcdfc0d5c29ed7c3d5c2c6d9d3d5d1d3d3dfc5dec49ed3dfdd">[email protected]</a>', // Service account email
        'scope': 'https://www.googleapis.com/auth/analytics.readonly',
// Only want to read data
        'aud': 'https://accounts.google.com/o/oauth2/token'
    },
    SIGNATURE_ALGORITHM = '**',
    SIGNATURE_ENCODE_METHOD = '**',
    GA_KEY_PATH = '**',
  //appends private key to the directory
    gaKey;

function urlEscape(source) {
    return source.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=+$/, '');
}

function base64Encode(obj) {
    var encoded = new Buffer(JSON.stringify(obj), 'utf8').toString('base64');
    return urlEscape(encoded);
}

function readPrivateKey() {
    if (!gaKey) {
        gaKey = fs.readFileSync(GA_KEY_PATH, 'utf8');
    }
    return gaKey;
}

var authorize = function (callback) {

    var self = this,
        now = parseInt(Date.now() / 1000, 10), // Google prefers seconds
        cipher,
        signatureInput,
        signatureKey = readPrivateKey(),
        signature,
        jwt;

    // Setup time values
    authClaimSet.iat = now;
    authClaimSet.exp = now + 60; // Token valid for one minute

    // Setup JWT source
    signatureInput = base64Encode(authHeader) + '.' + base64Encode(authClaimSet);

    // Generate JWT
    cipher = crypto.createSign('RSA-SHA256');
    cipher.update(signatureInput);
    signature = cipher.sign(signatureKey, 'base64');
    jwt = signatureInput + '.' + urlEscape(signature);

    // Send request to authorize this application
    request({
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        uri: 'https://accounts.google.com/o/oauth2/token',
        body: 'grant_type=' + escape('urn:ietf:params:oauth:grant-type:jwt-bearer') +
            '&assertion=' + jwt
    }, function (error, response, body) {
        if (error) {
            console.log(error);
            callback(new Error(error));
        } else {
            var gaResult = JSON.parse(body);
            if (gaResult.error) {
                callback(new Error(gaResult.error));
            } else {
                callback(null, gaResult.access_token);
            //    console.log(gaResult);
                console.log("Authorized");

            }
        }
    });

};

var request = require('request'),
    qs = require('querystring');

authorize(function (err, token) {
    if (!err) {
        // Retrieve total visits for a month

        var requestConfig = {
            'ids': 'ga:72333024',
            'dimensions': Dimension,
            'metrics': Metric,
            // 'sort': '-ga:users',
            'start-date': StartDate,
            'end-date': EndDate,
            'max-results': MaxResults
        };

        request({
            method: 'GET',
            headers: {
                'Authorization': 'Bearer ' + token // Use the auth token here
            },
            uri: 'https://www.googleapis.com/analytics/v3/data/ga?' + qs.stringify(requestConfig)
        }, function (error, resp, body) {
            console.log(body);
            var data = JSON.parse(body);
            console.log(data.totalsForAllResults);
            console.log(data.rows);
        });
    }
});
}

Attempting to access it externally:

var gaJSON = utils.getDataFromGA("ga:country", "ga:pageviews", "2011-08-04", "2014-09-12", "50");
res.send(gaJSON);

Questioning how to access the data variable at the end of the first method and call it externally.

Answer №1

When working with asynchronous methods like authorize, assigning data to a variable in the first function may result in that variable being undefined by the end of the function. To handle this issue effectively, utilizing callbacks is recommended.

If you need to return something related to the variable, consider adding a callback parameter to the first function and invoking it with the result.

callback(variable)

Answer №2

What is the reason for wanting to access it externally? If you absolutely must, then you should create a function that takes the "data" as an argument and call the function.

console.log(body);
var data = JSON.parse(body);
myFunction(data);

Ensure all your logic is contained within the "myFunction" that utilizes the 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

Protect against X-Forwarded-For spoofing with ELB and Node.js

Currently, I am examining the setup involving a public route utilizing an Elastic Load Balancer to open a port managed by PM2 which then launches a node app using the koa module. The IP address is currently being captured based on the X-Forwarded-For heade ...

Tips for correctly sending the response code from a Node.js API

I have a straightforward node-based API that is responsible for parsing JSON data, saving it into a Postgres database, and sending the correct response code (e.g., HTTP 201). Here is an excerpt of my code: router.route('/customer') .post(fu ...

Using a module's internal function as a callback in the "request" operation

Within my primary code, I execute the following: var module = require('./module') module.FooA(module.FooB); The contents of module.js are as follows: var request = require('request'); //using npm "request" exports.FooB = function(d ...

Discover information lacking a specific identifier

I am currently trying to retrieve items from my database using the mongoose .find() function. In my router, here is the code I have for extracting specific items from the URL. For instance: mydomainname.com/market?type=1&name=hi&stats=123 ...?t ...

How can I create a download link using GridFsBucket in Express?

I am looking for a way to create a direct download link for a file stored in mongoDB (GridFsBucket) using express without saving the file temporarily on the server. Here is the method I have tried: async function downloadFileFromDB(fileId) { var gridfsb ...

Set a variable equal to the output of an external function, but receive an undefined value in

I've been facing an issue where I'm trying to store the value of an external function in a JavaScript variable, but it keeps returning undefined. The external function in question is designed to search for a specific record within a database: f ...

Getting matched records from two different collections in MongoDBHow can you get matching records from two

How can I retrieve data from the deposit and coin_info collections where the coin id is the same in both collections? I attempted to use the lookup aggregation method, but ended up with an empty array as a result. var mongoose=require('mongoose&apos ...

Error message "Error: listen EADDRINUSE" is reported by node.js when calling child_process.fork

Whenever the 'child_process.fork('./driver')' command is executed, an error occurs: Error: listen EADDRINUSE at exports._errnoException (util.js:746:11) at Agent.Server._listen2 (net.js:1156:14) at listen (net.js:1182:10) ...

Leveraging the power of the npm Rocky package, we can implement a

I currently have a REST API service provided by a software, and instead of calling this API directly, I have added a proxy to it using the NPM module Rocky. With Rocky, I can forward my requests to my API service. However, in order to manipulate my respons ...

One strategy for transferring node modules that specify express routes to the primary index.js file

Imagine you have a npm module named project stored in your node_module folder. This module contains express routes defined within it. For instance: var express = require('express'); var router = express.Router(); router.get('/', funct ...

Guide on uploading personal projects on Sinopia (npm adduser not working for private repository)

After setting up a private npm registry using Sinopia, I am facing an issue - I cannot publish anything to it. In short: Sinopia does not support the npm adduser command, but has its own user management system. Npm requires a valid user created before u ...

Using Node.js to create child processes synchronously

Currently in search of a simple method to synchronously spawn a child_process. It's quite unexpected that there isn't any clear solution available. I haven't delved much into promises or async/await, so I'm starting from scratch Appr ...

Express app on Node.js running on ec2 micro instance extremely sluggish

Let's set the scene: Hosting on an EC2 micro instance Running MySQL 5.6 Utilizing a Redis server Node.js powering an Express-based app Nginx serving as a reverse front-end proxy. The performance is sluggish, painfully slow. Understandably, being on ...

Issue encountered while running the Laravel webmix command

C:\Users\MyName\project>npm start build npm ERR! Windows_NT 10.0.19041 npm ERR! argv "C:\\Program Files\\nodejs\\node.exe" "C:\\Program Files\\nodejs\\node_modules\\npm ...

Is there a way to transform this pledge back into a JSON array format?

My goal with this code is to retrieve a JSON array from my server. var students_list; const library_address = 'http://localhost:17330' async function fetchData(param1, param2) { if(param1 == 'getdata') { const response ...

`Retrieve session data stored in Redis in CodeIgniter`

I have implemented a basic login system that saves the user's data in a session array, including the username and user ID. $sessionData=[ 'username'=>/*loggedInUser*/, 'user_id'=>/*userID of the l ...

Unable to render images in Angular client due to issues with accessing upload path in Express Node.js backend

I've been struggling with the issue of displaying images on the Angular client for a while now, despite going through numerous similar questions. The files are successfully uploaded to the upload folder and their details are stored in the MongoDB data ...

The TransactWriteItems API encounters issues when trying to process an update group containing more than 10 items. An error is generated stating: "Member must be no more than 10

Issue Encountering an error with the TransactWriteItems API when attempting to update a group of more than 10 items, despite the API being expected to support up to 25. According to the AWS TransactWriteItems API Documentation: TransactWriteItems is a ...

Adjust the value based on selection

I aim to display another div when either the Full Time or Part Time option is selected. Additionally, I would like to calculate a different value for each option; if 'Part Time' is chosen, PrcA should change to PrcB. Here is the code snippet tha ...

Having trouble with installing Typescript on a MacBook?

I have been attempting to follow the instructions provided on TypeScriptLang.org but for some reason, I am unable to successfully download typescript. This is what I have tried so far: mkotsollariss-MacBook-Pro:/ mkotsollaris$ which node /usr/local/bin/n ...