Как мне изменить все вхождения свойства (включая вложенные) в объекте перед отправкой ответа JSON?

#node.js #express

#node.js #выразить

Вопрос:

У меня есть объект, созданный путем синтаксического анализа некоторого JSON. Данные JSON выглядят следующим образом:

   {
    "id": "fan",
    "name": "My super awesome fan",
    "image": "Icon.png",
    "details": {
      "parts": [
        {
          "name": "base",
          "image": "base.png"
        },
        {
          "name": "blades",
          "image": "blade.png"
        }
      ],
      "sale": {
        "value": "prime",
        "image": "PrimeDay.png"
      }
    }
  }
  

Значения в свойстве image указывают на файлы, расположенные в каталоге «public», который обслуживается с помощью express.static . Например, файл blade.png находится по адресу:

 public
  --products
    --fan (this is the same as the id property)
      --blade.png
  

Теперь, когда выполняется запрос для получения сведений об этом объекте, я хочу изменить свойство image объекта, отправленного в ответе, чтобы ответ JSON выглядел следующим образом:

   {
    "id": "fan",
    "name": "My super awesome fan",
    "image": "http://localhost:3000/products/fan/icon.png",
    "details": {
      "parts": [
        {
          "name": "base",
          "image": "http://localhost:3000/products/fan/base.png"
        },
        {
          "name": "blades",
          "image": "http://localhost:3000/products/fan/blade.png"
        }
      ],
      "sale": {
        "value": "prime",
        "image": "http://localhost:3000/products/fan/PrimeDay.png"
      }
    }
  }

  
  

Я пошел по пути использования промежуточного программного обеспечения express для создания URL-адреса, указывающего на путь использования

 const url = req.protocol   '://'   req.get('host')
  

Как мне использовать это url значение для изменения объекта ответа?
Я не хочу жестко указывать полный путь локального хоста к изображениям в JSON, поскольку путь может измениться при развертывании.

Ответ №1:

Я смог решить эту проблему, частично используя решение Чарли. Единственная причина, по которой я не мог использовать его полностью, заключалась в том, что fan часть URL-адреса также является динамической и зависит от id свойства в данных JSON.

Вот мой подход:

 setImagePaths = (data) => {
    const baseUrl = 'http://localhost:3000/products/'
    const baseId = data.id;

    const patchImagePaths = (obj) => {
        Object.keys(obj).forEach(key => {
            if (typeof obj[key] === 'object') {
                return patchImagePaths(obj[key]);
            }
            if (key === 'image') {
                obj[key] = baseUrl   baseId   '/'   obj[key];
            }
        });
    }

    patchImagePaths(data);
}
  

Ответ №2:

Вы можете изменить свой объект ответа с помощью рекурсивной функции для обновления свойств изображения:

 var myObject =   {
  "id": "fan",
  "name": "My super awesome fan",
  "image": "Icon.png",
  "details": {
    "parts": [
      {
        "name": "base",
        "image": "base.png"
      },
      {
        "name": "blades",
        "image": "blade.png"
      }
    ],
    "sale": {
      "value": "prime",
      "image": "PrimeDay.png"
    }
  }
}
;

const url = "http://localhost:3000/products/fan/";
//You can use here your url function with whatever output it has.

function resetImages (obj) {
  Object.keys(obj).forEach(function (key) {
      if (Array.isArray(obj[key])) {
          let arr = obj[key];
          arr.map((i)=>{
            return i.image = url i.image;
          });
          return arr;
      }
      if (typeof obj[key] === 'object') {
          return resetImages(obj[key]);
      }
      if(key==="image") {
        obj[key]=url obj[key];
      }
  });
}




resetImages(myObject);
console.log(JSON.stringify(myObject));

**Output:**

{"id":"fan","name":"My super awesome fan","image":"http://localhost:3000/products/fan/Icon.png","details":{"parts":[{"name":"base","image":"http://localhost:3000/products/fan/base.png"},{"name":"blades","image":"http://localhost:3000/products/fan/blade.png"}],"sale":{"value":"prime","image":"http://localhost:3000/products/fan/PrimeDay.png"}}}