This is a skeleton of a program I'm writing where I am trying to eliminate as many global objects and variables as I can to try to make it more reusable. As is (with the commented parts of the Config class) it works and the root page of its web site can get the device "name" from the Config class. If I try to add any more items to my Config class, the lambda functions that I normally write for page handlers can no longer access ANY variables from the WebServer class, much less the Config class (all the methods are still callable).
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <wifiCreds.h>
#include <LittleFS.h>
#include <ESPAsyncWebServer.h>
class Config {
public:
Config();
virtual ~Config() {};
bool setName(char *val);
struct {
char name[32];
//char ssid[32];
//char pass[32];
//char ntp[32];
} host;
};
Config::Config() {
LittleFS.begin();
}
bool Config::setName(char *val) {
strlcpy(host.name, val, sizeof(host.name));
return true;
}
class WebServer {
public:
WebServer(Config *conf);
virtual ~WebServer() {};
bool setup();
char detail[32];
void funcPage(AsyncWebServerRequest *request);
private:
AsyncWebServer *web;
Config *config;
};
WebServer::WebServer(Config *conf) {
web = new AsyncWebServer(80);
config = conf;
}
bool WebServer::setup() {
web->on("/", HTTP_GET, [this](AsyncWebServerRequest *request) {
AsyncResponseStream *response = request->beginResponseStream("text/plain");
response->setCode(200);
response->print("The name passed to this instance was ");
response->print(config->host.name);
request->send(response);
});
web->on("/func", HTTP_GET, [this](AsyncWebServerRequest *r) { funcPage(r); });
web->begin();
return true;
}
void WebServer::funcPage(AsyncWebServerRequest *request) {
AsyncResponseStream *response = request->beginResponseStream("text/plain");
response->setCode(200);
response->print("Alternate page to see that the device name is ");
response->print(config->host.name);
request->send(response);
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.isConnected() != 1) {
delay(100);
}
Serial.print(F("Connected to "));
Serial.println(WIFI_SSID);
Serial.print(F("IP Address: "));
Serial.println(WiFi.localIP());
Config conf;
conf.setName("Garage");
WebServer srv(&conf);
srv.setup();
}
void loop() {
// put your main code here, to run repeatedly:
}
If I uncomment any other variables in the Config class, neither page will be able to access the value of host.name. Can anyone please educate me on what I'm doing wrong here?
The actual Config class is supposed to read a JSON file in the LittleFS partition, if it exists, and the actual WebServer class provides forms and ajax endpoints for changing/setting config items. When it boots, if there is no configuration it starts the SoftAP to allow one to put initial settings in to get it onto a network. Making Config global it all worked, but it's my understanding that writing it that way isn't "right."