Multiple widget display error

Hi,
I got this error when create 2+ widget on springboard.
Only 1 widget displayed at the same time (different script for each widget). Example picture:

Please help me,
Thank you!

Seems that your other widget that isn’t displaying was set properly. What code does it have?

Hi mvan231,
Both script has the same code, with the “renderToWidget” part like this, (I just duplicate script):


If Script-1 render correctly then Script-2 will got error, and vice versa.

I think if there are an “id of widget” param may fix this problem :joy:

The full code:

const fileSvc = FileManager.local();
const fileLocation = fileSvc.documentsDirectory() + '/vinassid.txt';
let readedSsid = '';
let dateSvc = new DateFormatter();
dateSvc.dateFormat = 'HH:mm:ss';

const fontName = 'Trebuchet MS';
const fontSizes = {
  bigger: 60,
  big: 40,
  normal: 16,
  small: 10
};
const colors = {
  red: '#F44336',
  green: '#4caf50',
  blue: '#007bff',
  orange: '#ff5722',
  white: '#ffffff',
  black: '#000000',
  indigo: '#3f51b5'
};

const defaultHeader = {
  'Content-Type': 'application/json',
  'Accept': '*/*',
  'Accept-Encoding': 'gzip, deflate, br',
  'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'
}

function doLogin() {
  const reqLogin = new Request('https://************/mapi/services/authen_msisdn');
  reqLogin.headers = defaultHeader;
  reqLogin.method = 'post';
  reqLogin.body = JSON.stringify({
    'device_info': 'Pixel',
    'fcm_registration_token': '***********',
    'mode': 'password',
    'msisdn': '***********',
    'password': '***********',
    'session': ''
  });
  return reqLogin.loadJSON();
}

function readSsid() {
  readedSsid = fileSvc.fileExists(fileLocation) ? fileSvc.readString(fileLocation) : '';
  return readedSsid;
}

function getRemain4gData() {
  const req = new Request('https://***********/mapi/services/mobile_data_get_high_bandwidth');
  req.headers = defaultHeader;
  req.method = 'post';
  req.body = JSON.stringify({
    'msisdn': '***********',
    'session': readedSsid
  });
  return req.loadJSON();
}

function createWidget(stringData) {
  const widget = new ListWidget();
  
  const bgColor = new LinearGradient();
  bgColor.colors = [new Color(colors.blue), new Color(colors.indigo)];
  bgColor.locations = [0.0, 1.0];
  widget.backgroundGradient = bgColor;
  widget.useDefaultPadding(); // setPadding(10, 15, 15, 10);

  const stack = widget.addStack();
  stack.centerAlignContent();
  stack.layoutHorizontally();
  stack.spacing = 2;
  stack.size = new Size(160, 0);

  // Line 1 - Title
  const titleLine = stack.addText(`4G Data Remain`);
  titleLine.textColor = Color.white();
  titleLine.font = new Font(fontName, fontSizes.normal);


  const stack2 = widget.addStack();
  stack2.centerAlignContent();
  stack2.layoutHorizontally();
  stack2.spacing = 2;
  stack2.size = new Size(160, 0);


  // Line 2 - Data remain
  const data4gRemainLine = stack2.addText(stringData);
  let numOfDataRemain = 0;
  try {
    numOfDataRemain = parseInt(stringData, 10);
    if (numOfDataRemain >= 1500) {
      data4gRemainLine.textColor = new Color(colors.green);
    } else if (500 < numOfDataRemain && numOfDataRemain < 1500) {
      data4gRemainLine.textColor = new Color(colors.orange);
    } else {
      data4gRemainLine.textColor = new Color(colors.red);
    }
  } catch {
    numOfDataRemain = 0;
    data4gRemainLine.textColor = new Color(colors.red);
  }
  data4gRemainLine.font = Font.boldSystemFont(fontSizes.bigger);


const stack2b = widget.addStack();
  stack2b.centerAlignContent();
  stack2b.layoutHorizontally();
  stack2b.spacing = 2;
  stack2b.size = new Size(160, 0);
  
  const megabyteLine = stack2b.addText(`Megabytes`);
  megabyteLine.textColor = Color.yellow();
  megabyteLine.font = new Font(fontName, fontSizes.normal);

const stack2c = widget.addStack();
  stack2c.centerAlignContent();
  stack2c.layoutVertically();
  stack2c.spacing = 2;
  stack2c.size = new Size(160, 0);
  stack2c.addSpacer(15);

const stack3 = widget.addStack();
  stack3.centerAlignContent();
  stack3.layoutHorizontally();
  stack3.spacing = 2;
  stack3.size = new Size(160, 0);



// Line 3 - Check count
  const checkCountLine = stack3.addText(`Last check: ${dateSvc.string(new Date())}`);
  checkCountLine.textColor = Color.white();
  checkCountLine.font = new Font(fontName, fontSizes.small);


  return widget;
}

async function renderToWidget(stringData) {
  let w = await createWidget(stringData);
  Script.setWidget(w);
  Script.complete();
}

/** *******************************
 *             MAIN               *
 **********************************/

runMain();

function runMain() {
  if (!readSsid()) {
    doLogin().then(resLogin => {
      if (resLogin.error_code === '0') {
        readedSsid = resLogin.session;
        fileSvc.write(fileLocation, Data.fromString(resLogin.session));
        getRemain4gData().then(resData => {
          if (resData.error_code === '0') {
            console.log(resData.result.high_bandwidth_volume_remain);
            renderToWidget(resData.result.high_bandwidth_volume_remain + '');
          } else {
            fileSvc.remove(fileLocation);
            renderToWidget('Err.Fetch');
          }
        }, (rejected) => {
          fileSvc.remove(fileLocation);
          renderToWidget('Rej.Fetch');
        });
      } else {
        fileSvc.remove(fileLocation);
        renderToWidget('Err.Login');
      }
    }, (rejected) => {
      fileSvc.remove(fileLocation);
      renderToWidget('Rej.Login');
    });;
  } else {
    getRemain4gData().then(resData => {
      if (resData.error_code === '0') {
        renderToWidget(resData.result.high_bandwidth_volume_remain + '')
      } else {
        fileSvc.remove(fileLocation);
        renderToWidget('Err.Fetch');
      }
    }, (rejected) => {
      fileSvc.remove(fileLocation);
      renderToWidget('Rej.Fetch');
    });
  }
}

This is an interesting layout of code. I think the code won’t work for me due to having no network credentials. However, after looking at it, I would recommend simplifying the code as much as possible to find why it’s not reaching the end of the function.

I found that there was a request to load JSON that didn’t have an async defined on the function and was not using await.

Can you try the below and see if it works better for you?


const fileSvc = FileManager.local();
const fileLocation = fileSvc.documentsDirectory() + '/vinassid.txt';
let readedSsid = '';
let dateSvc = new DateFormatter();
dateSvc.dateFormat = 'HH:mm:ss';

const fontName = 'Trebuchet MS';
const fontSizes = {
  bigger: 60,
  big: 40,
  normal: 16,
  small: 10
};
const colors = {
  red: '#F44336',
  green: '#4caf50',
  blue: '#007bff',
  orange: '#ff5722',
  white: '#ffffff',
  black: '#000000',
  indigo: '#3f51b5'
};

const defaultHeader = {
  'Content-Type': 'application/json',
  'Accept': '*/*',
  'Accept-Encoding': 'gzip, deflate, br',
  'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'
}


/** *******************************
 *             MAIN               *
 **********************************/

//runMain();

//

//

let errorString
//function runMain() {
  if (!readSsid()) {
    doLogin().then(resLogin => {
      if (resLogin.error_code === '0') {
        readedSsid = resLogin.session;
        fileSvc.write(fileLocation, Data.fromString(resLogin.session));
        getRemain4gData().then(resData => {
          if (resData.error_code === '0') {
            console.log(resData.result.high_bandwidth_volume_remain);
            /*renderToWidget(*/ errorString= resData.result.high_bandwidth_volume_remain + ''//);
          } else {
            fileSvc.remove(fileLocation);
            /*renderToWidget(*/ errorString= 'Err.Fetch'//);
          }
        }, (rejected) => {
          fileSvc.remove(fileLocation);
          /*renderToWidget(*/ errorString= 'Rej.Fetch'//);
        });
      } else {
        fileSvc.remove(fileLocation);
        /*renderToWidget(*/ errorString= 'Err.Login'//);
      }
    }, (rejected) => {
      fileSvc.remove(fileLocation);
      /*renderToWidget(*/ errorString= 'Rej.Login'//);
    });;
  } else {
    getRemain4gData().then(resData => {
      if (resData.error_code === '0') {
        /*renderToWidget(*/ errorString= resData.result.high_bandwidth_volume_remain + ''//)
      } else {
        fileSvc.remove(fileLocation);
        /*renderToWidget(*/ errorString= 'Err.Fetch'//);
      }
    }, (rejected) => {
      fileSvc.remove(fileLocation);
      /*renderToWidget(*/ errorString= 'Rej.Fetch'//);
    });
  }
//}

  const widget = new ListWidget();
  
  const bgColor = new LinearGradient();
  bgColor.colors = [new Color(colors.blue), new Color(colors.indigo)];
  bgColor.locations = [0.0, 1.0];
  widget.backgroundGradient = bgColor;
  widget.useDefaultPadding(); // setPadding(10, 15, 15, 10);

  const stack = widget.addStack();
  stack.centerAlignContent();
  stack.layoutHorizontally();
  stack.spacing = 2;
  stack.size = new Size(160, 0);

  // Line 1 - Title
  const titleLine = stack.addText(`4G Data Remain`);
  titleLine.textColor = Color.white();
  titleLine.font = new Font(fontName, fontSizes.normal);


  const stack2 = widget.addStack();
  stack2.centerAlignContent();
  stack2.layoutHorizontally();
  stack2.spacing = 2;
  stack2.size = new Size(160, 0);


  // Line 2 - Data remain
  const data4gRemainLine = stack2.addText(errorString);
  let numOfDataRemain = 0;
  try {
    numOfDataRemain = parseInt(stringData, 10);
    if (numOfDataRemain >= 1500) {
      data4gRemainLine.textColor = new Color(colors.green);
    } else if (500 < numOfDataRemain && numOfDataRemain < 1500) {
      data4gRemainLine.textColor = new Color(colors.orange);
    } else {
      data4gRemainLine.textColor = new Color(colors.red);
    }
  } catch (e){
    numOfDataRemain = 0;
    data4gRemainLine.textColor = new Color(colors.red);
  }
  data4gRemainLine.font = Font.boldSystemFont(fontSizes.bigger);


const stack2b = widget.addStack();
  stack2b.centerAlignContent();
  stack2b.layoutHorizontally();
  stack2b.spacing = 2;
  stack2b.size = new Size(160, 0);
  
  const megabyteLine = stack2b.addText(`Megabytes`);
  megabyteLine.textColor = Color.yellow();
  megabyteLine.font = new Font(fontName, fontSizes.normal);

const stack2c = widget.addStack();
  stack2c.centerAlignContent();
  stack2c.layoutVertically();
  stack2c.spacing = 2;
  stack2c.size = new Size(160, 0);
  stack2c.addSpacer(15);

const stack3 = widget.addStack();
  stack3.centerAlignContent();
  stack3.layoutHorizontally();
  stack3.spacing = 2;
  stack3.size = new Size(160, 0);



// Line 3 - Check count
  const checkCountLine = stack3.addText(`Last check: ${dateSvc.string(new Date())}`);
  checkCountLine.textColor = Color.white();
  checkCountLine.font = new Font(fontName, fontSizes.small);

Script.setWidget(widget)
Script.complete()
widget.presentSmall()

function doLogin() {
  const reqLogin = new Request('https://************/mapi/services/authen_msisdn');
  reqLogin.headers = defaultHeader;
  reqLogin.method = 'post';
  reqLogin.body = JSON.stringify({
    'device_info': 'Pixel',
    'fcm_registration_token': '***********',
    'mode': 'password',
    'msisdn': '***********',
    'password': '***********',
    'session': ''
  });
  return reqLogin.loadJSON();
}

function readSsid() {
  readedSsid = fileSvc.fileExists(fileLocation) ? fileSvc.readString(fileLocation) : '';
  return readedSsid;
}

async function getRemain4gData() {
  const req = new Request('https://***********/mapi/services/mobile_data_get_high_bandwidth');
  req.headers = defaultHeader;
  req.method = 'post';
  req.body = JSON.stringify({
    'msisdn': '***********',
    'session': readedSsid
  });
  return await req.loadJSON();
}

1 Like

I don’t know how but It’s working :joy: Thank you very much!

The version I sent is working?

yeah, I think the probplem is async/await :joy:

Agree. I’m glad it’s working!

1 Like