Search code examples
node.jstypescriptnode-fetch

How to use nested object/array notation in node-fetch headers?


I am trying to make a fetch() api call from typescript application based on below specification:

I am getting following error when trying to use nested object/array value for headers in node-fetch call.

(property) RequestInit.headers?: HeadersInit Type '{ 'Content-Type': string; 'Content-Disposition': string; 'Memsource': { 'targetLangs': string[]; }; }' is not assignable to type 'HeadersInit'. Type '{ 'Content-Type': string; 'Content-Disposition': string; 'Memsource': { 'targetLangs': string[]; }; }' is missing the following properties from type 'Headers': forEach, append, delete, get, and 7 more.ts(2322) index.d.ts(45, 5): The expected type comes from property 'headers' which is declared here on type 'RequestInit'

Below is the line of the code giving the problem.

let project: Promise<Response> = await fetch(apiURL, {
    method: 'POST',
    headers: {
      'Content-Disposition': 'd:/_export/en_US.json',
      'Memsource': { 'targetLangs': ['fr_fr', 'es_es'] },
    },
  }).then(res => res.json())
    .then(json => json)
    .catch(err => console.log(err));

What should I do to fix the problem? Am I not allowed to use this notation?


Solution

  • I researched this matter really hard and learned hat HTTP request headers (or Headers object in Node-Fetch) supports only simple key/value pairs. That is why the nested json value was failing in this context.

    I tired to make the nested value a simple json string by put quotes around the entire json and escaping all the inner quotes like below and it worked like charm.

    'Memsource': '{ \'targetLangs\': [\'fr_fr\', \'es_es\'] }'
    

    Once I confirmed it working, I changed it to JSON.stringify() statement and it worked good. Oh, I had to make a small mistake correction in the 'Content-Disposition' value.

    var customHeader = {'targetLangs': ['fr_fr', 'es_es'],};
    let project: Promise<Response> = await fetch(apiURL, {
        method: 'POST',
        headers: {
          'Content-Disposition': 'filename=d:/_export/en_US.json',
          'Memsource': JSON.stringify(customHeader),
        },
      }).then(res => res.json())
        .then(json => json)
        .catch(err => console.log(err));
    

    I thought I might share just in case someone else needs this information.