Passing json object by reference

Im am attempting to download temperature from an OpenWeather station then upload the temperature to Thingspeak. I have created three functions (1) openWeather that creates json buffer and parses data and (2) passTemp which creates pass by reference function for temperature and (3) thingSpeak that uploads the temperature. I am having problems passing the temp data by reference from the openWeather function to the thingsSpeak function. The openWeather function parses and prints the temp data correctly. When I try and call the passTemp function and pass the temp data to thingsSpeak I receive compiler area in thingSpeak function 'root not declared in this scope'. I have spent considerable time finding and trying different json and pass by reference syntax but cannot get this to work. Any suggestions would be welcome.

#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>

//Connection info to Internet
const char* ssid = "SSID";
const char* password = "Password";

//Connection info to Open Weather
String nameOfCity = "City, US";
String apiKey = "Apikey";

WiFiClient client;
int status = WL_IDLE_STATUS;
char server[] = "api.openweathermap.org";

void setup() {
  Serial.println ("Start Void Setup");
  Serial.begin(115200);
  delay(10);
}
void loop() {
  openWeather();
  thingSpeak();
  delay(1 * 60 * 10000);
}
void openWeather() {
  Serial.println("\nStarting connection to server...");
  // close any connection before send a new request to allow client make connection to server
  client.stop();
  // if you get a connection, report back via serial:
  if (client.connect(server, 80)) {
    Serial.println("connected to server");
    client.print("GET /data/2.5/forecast?");
    client.print("q=" + nameOfCity);
    client.print("&appid=" + apiKey);
    client.print("&cnt=3");
    client.println("&units=imperial");
    client.println("Host: api.openweathermap.org");
    client.println("Connection: close");
    client.println();
  } else {
    Serial.println("unable to connect");
  }
  delay(1000);
  String line = "";
  while (client.connected()) {
    line = client.readStringUntil('\n');
    Serial.println("parsingValues");
    //create a json buffer where to store the json data
    DynamicJsonBuffer jsonBuffer(4000);
    JsonObject& root = jsonBuffer.parseObject(line);
    if (!root.success()) {
      Serial.println("parseObject() failed");
      return;
    }
    //get the data from the json tree
    String city = root["city"]["name"];
    float tempNow = root["list"][0]["main"]["temp"];

    Serial.println("  ");
    Serial.println(city);
    Serial.print ("Current temperature = ");
    Serial.println(tempNow);
    client.stop();
  }
}
void passTemp(JsonObject& root) { //Pass temp by reference
  float tempNow = root["temp"];
}
void thingSpeak() {
  passTemp(root); //’root not declared in this scope’
  Serial.print("City temperature: ");
  Serial.println(tempNow);
}

you create your 'root' variable inside openWeather() so when that function is done, that variable goes out of scope and no longer exists.

It would be much easier to just make jsonObject and root a global variables

I declared jsonObject and root as global variables and commented out the passTemp function. The problem is when they are called in thingSpeak using a ['list'][0] I get a compiler error indicated" Invalid types 'cont char[int]' for array subscript". i tried obtaining the number from the json array using other methods without the list number but just get wrong numbers that do not match the temp shown in openWeather. I tried including the passTemp function and called in thingSpeak but receive error "Invalid initialization of reference of type 'Ardunio:JasonObject' from expression of type 'char'". Not sure how to implement jsonObject and root as global variables?

#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>

//Connection info to Internet
const char* ssid = "SSID";
const char* password = "Password";


//Connection info to Open Weather
String nameOfCity = "City, US";
String apiKey = "Apikey";

//Declare global variables
char jsonObject;
char root;

WiFiClient client;
int status = WL_IDLE_STATUS;
char server[] = "api.openweathermap.org";

void setup() {
  Serial.println ("Start Void Setup");
  Serial.begin(115200);
  delay(10);
}
void loop() {
  openWeather();
  thingSpeak();
  delay(1 * 60 * 10000);
}
void openWeather() {
  Serial.println("\nStarting connection to server...");
  // close any connection before send a new request to allow client make connection to server
  client.stop();
  // if you get a connection, report back via serial:
  if (client.connect(server, 80)) {
    Serial.println("connected to server");
    client.print("GET /data/2.5/forecast?");
    client.print("q=" + nameOfCity);
    client.print("&appid=" + apiKey);
    client.print("&cnt=3");
    client.println("&units=imperial");
    client.println("Host: api.openweathermap.org");
    client.println("Connection: close");
    client.println();
  } else {
    Serial.println("unable to connect");
  }
  delay(1000);
  String line = "";
  while (client.connected()) {
    line = client.readStringUntil('\n');
    Serial.println("parsingValues");
    //create a json buffer where to store the json data
    DynamicJsonBuffer jsonBuffer(4000);
    JsonObject& root = jsonBuffer.parseObject(line);
    if (!root.success()) {
      Serial.println("parseObject() failed");
      return;
    }
    //get the data from the json tree
    String city = root["city"]["name"];
    float tempNow = root["list"][0]["main"]["temp"];

    Serial.println("  ");
    Serial.println(city);
    Serial.print ("Current temperature = ");
    Serial.println(tempNow);
    client.stop();
  }
}
void passTemp(JsonObject& root) { //Pass temp by reference
  float tempNow = root["temp"];
}
void thingSpeak() {
   //float tempNow = root["temp"]; //Produces wrong number (No passTemp function)
   // float tempNow = root["base"]["stations"]["main"]["temp"]; //Produces different wrong number (No 
       passTemp function)
   // float tempNow = root["list"][0]["main"]["temp"]; //Invalid types 'cont char[int]' for array subscript 
      (No passTemp function)
  //  passTemp(root); // Invalid initialization of reference of type 'Ardunio:JasonObject' from expression of 
 
  Serial.print("City temperature: ");
  Serial.println(tempNow);
}

First, make sure the JSON data structure you want to parse. the data obtained from the request is like this (city=London)

{
	"coord":{"lon":-0.13,"lat":51.51},
	"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04n"}],
	"base":"stations",
	"main":{"temp":50.86,"feels_like":41.2,"temp_min":50,"temp_max":51.8,"pressure":1010,"humidity":71},
	"visibility":10000,
	"wind":{"speed":13.87,"deg":330},
	"clouds":{"all":90},
	"dt":1601184568,
	"sys":{"type":1,"id":1414,"country":"GB","sunrise":1601186107,"sunset":1601228856},
	"timezone":3600,
	"id":2643743,
	"name":"London",
	"cod":200
}

so if you want tmp data, it should function like this

          float tempNow = root["main"]["temp"];

sorry I used this code to try it

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
 
const char* ssid = "";
const char* password = "";
String apiKey = "";
String payload; 
void setup () {
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  Serial.print("Connecting..");
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print("."); 
  }
  Serial.println();
 
}
 
void loop() {
   if (WiFi.status() == WL_CONNECTED) { //Check WiFi connection status
          String address ="http://api.openweathermap.org/data/2.5/weather?q=London&appid="; //http://api.openweathermap.org/data/2.5/weather?q=London&appid=c0e26b29eace61eded7b43d12e43894b&cnt=3&units=imperial
          address += apiKey ;
          address += "&cnt=3&units=imperial";
          HTTPClient http;  //Declare an object of class HTTPClient
          //http.begin("http://jsonplaceholder.typicode.com/users/1");  //Specify request destination
          http.begin(address);  //Specify request destination
          int httpCode = http.GET();                                                                  //Send the request
           
          if (httpCode > 0) { //Check the returning code
           
          payload = http.getString();   //Get the request response payload
          Serial.println(payload);                     //Print the response payload
          
      }
     
      http.end();   //Close connection
      DynamicJsonBuffer jsonBuffer(4000);
          JsonObject& root = jsonBuffer.parseObject(payload);
          // Test if parsing succeeds.
          if (!root.success()) {
            Serial.println("parseObject() failed");
            return;
          }
          float tempNow = root["main"]["temp"];
          float humNow = root["main"]["humidity"];
          Serial.println(tempNow);
          Serial.println(humNow);
          
    }
delay(30000);    //Send a request every 30 seconds
}

Thanks so much for the help bln64 and danangs. I am looking over my json parsing (I'm learning a lot about this). and seeing why mine doesn't match yours and will get this working. Its a good way to make this function. I was able to pass the json variable by creating a pointer. I added float tempNow as a global variable, then added float *PRtemp in the openWeather declaration. Within openWeather after the temp was parsed I added *PRtemp = tempNow;. Then finally called openWeather(&tempNow) in thingSpeak.

#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>

//Connection info to Internet
const char* ssid = "SSID";
const char* password = "Password";

//Connection info to Open Weather
String nameOfCity = "City, US";
String apiKey = "Apikey";

//Declare global variable
float tempNow = 0;       //add tempNow as global

WiFiClient client;
int status = WL_IDLE_STATUS;
char server[] = "api.openweathermap.org";

void setup() {
  Serial.println ("Start Void Setup");
  Serial.begin(115200);
  delay(10);
}
void loop() {
  openWeather();
  thingSpeak();
  delay(1 * 60 * 10000);
}
void openWeather (float *PRtemp) {           //add *PRtemp pointer to declaration

  Serial.println("\nStarting connection to server...");
  // close any connection before send a new request to allow client make connection to server
  client.stop();
  // if you get a connection, report back via serial:
  if (client.connect(server, 80)) {
    Serial.println("connected to server");
    client.print("GET /data/2.5/forecast?");
    client.print("q=" + nameOfCity);
    client.print("&appid=" + apiKey);
    client.print("&cnt=3");
    client.println("&units=imperial");
    client.println("Host: api.openweathermap.org");
    client.println("Connection: close");
    client.println();
  } else {
    Serial.println("unable to connect");
  }
  delay(1000);
  String line = "";
  while (client.connected()) {
    line = client.readStringUntil('\n');
    Serial.println("parsingValues");
    //create a json buffer where to store the json data
    DynamicJsonBuffer jsonBuffer(4000);
    JsonObject& root = jsonBuffer.parseObject(line);
    if (!root.success()) {
      Serial.println("parseObject() failed");
      return;
    }
    //get the data from the json tree
    String city = root["city"]["name"];
    float tempNow = root["list"][0]["main"]["temp"];

   *PRtemp = tempNow;      //Assign tempNow value to pointer

    Serial.println("  ");
    Serial.println(city);
    Serial.print ("Current temperature = ");
    Serial.println(tempNow);
    client.stop();
  }
}
void passTemp(JsonObject& root) { //Pass temp by reference
  float tempNow = root["temp"];
}
void thingSpeak() {
  
openWeather(&tempNow);      //call value at *PRtemp ointer and assign to tempNow

  Serial.print("City temperature: ");
  Serial.println(tempNow);
}

You're over-complicating and convoluting things. 'tempNow' is a global variable, no need to pass around a pointer to it.