访问nodejs中各个级别的嵌套JSON对象

时间:2017-05-19 06:27:38

标签: javascript json node.js

我将数据存储在像这样的变量

var products = [
    {
        place1:[
            {id: 1, name: "choc1", price: 20},
            {id: 2, name: "choc2", price: 30}
        ],
        place2:[
            {id: 1, name: "coffee", price: 50}
        ],
        place3: [
            {id: 1, name: "oil1", price: 10},
            {id: 2, name: "oil2", price: 60},
            {id: 3, name: "oil3", price: 70}
        ]
    }
];

我想写一个get方法,以便它响应这个Url

http://myurl.com/place1/1

get方法的格式为

router.get('/:place/:id([0-9]{1,})', function(req, res){
//  send the exact data as requested
}

我不明白的是如何验证链接。即,验证该地点是否在products变量中,然后验证该产品变量中是否存在该ID,然后如果存在,则将其发送回服务器,否则发送错误响应。

4 个答案:

答案 0 :(得分:1)

以下是使用点表示法从对象获取嵌套值的函数:

/**
 * Treating field name with dot in it as a path to nested value.
 * For example 'settings.day' is path to { settings: { day: 'value' } }
 *
 * @param {{}} object Object where to look for a key
 * @param {string} field Dot notated string, which is path to desired key
 * @returns {*}
 */
getNestedValue = function (object, field) {
    if (!object) {
        return null;
    }

    var path   = field.split('.');
    while (path.length && (object = object[path.shift()]));

    return object;
};

答案 1 :(得分:0)

if (products[0][req.params.place] === undefined)
  console.log("place doesnt exist");
else {
    if (products[0][req.params.place][req.params.id - 1] === undefined)
        console.log ("id doesnt exist");
    else {
        ....
    }
}

答案 2 :(得分:0)

以下是如何访问嵌套的JSON对象:

if(products[0][req.params.place]) {
    var place = products[0][req.params.place];
    var resSent = false;
    for(var obj in place) {
        if(place[obj].id == req.params.id) {
            resSent = true;
            res.send(place[obj]);
        }
    }
    if(!resSent) {
        res.send(new Error('Not Found'));
    }
} else {
    res.send(new Error('Not Found'));
}

答案 3 :(得分:0)

这是路由器的开始。我没有时间去处理产品的过滤,因为结构有点奇怪。如果你使用它作为基础,你需要做一些微小的mod来使用节点中的req和res对象,但正则表达式是合理的。

EDIT .. 看起来你改变了url reg,如果没有像前一个模式那样指定,我会留给你弄清楚如何用适当的正则表达式替换:capture:id(RegEx)

请参阅下面的内联评论,了解其工作原理。



// convert the search string into regEx string and captures from string
const regexify = str => ({
  captures: str.match(/:([a-z]+)/g).map(x => x.replace(':', '')),
  reg: '^' + str.replace(/\//g, '\\/').replace(/:\w+/g, '') + '$'
})

const parse = x => parseInt(x) == x ? parseInt(x) : x

class Router {
  constructor(object) {
    this.routes = []
    this.__onError = console.error.bind(console)
  }
  get(uri, cb) {
    const { captures, reg } = regexify(uri)
    // create a new route
    this.routes.push({
      cb,
      reg: new RegExp(reg),
      captures
    })
    return this
  }
  error(cb) {
    this.__onError = cb
  }
  exec(uri/*, req, res*/) {
    // find a matching route
    const route = this.routes.find(x => x.reg.test(uri))
    
    if (!route) {
      return this.__onError(`could not find route: ${uri}`)
    }
    
    const params = uri
      .match(route.reg)                     // get the params from the url
      .slice(1, route.captures.length + 1)  // remove unwanted values
      .map(parse)                           // parse numbers
      
    // call the route callback with the correct params injected
    route.cb(
      /*req,
      res,*/
      ...params
    )
  }
}

// instantiate the router
const router = new Router

// create router methods
router.get('/:place([a-z0-9]+)/:id([0-9]{1,})', (/*req, res, */place, id) => {
  console.log(
    'first route callback:',
    place, id
  )
})

router.get('/:place([a-z0-9]+)', (/*req, res, */place) => {
  console.log(
    'second route callback:',
    place
  )
})

router.error(err => {
  console.error(err)
})
// run the router on request
router.exec('/place1/1'/*req, res */)

// proof of concept below
router.exec('/place1'/*req, res */)
router.exec('/1/fail'/*req, res */)