为什么JS无法识别嵌套JSON中的json变量。

huangapple go评论65阅读模式
英文:

Why is JS not recognizing the json variable in nested json

问题

以下是代码部分的翻译:

我正在尝试在HTML中使用JavaScript设置动态个人资料卡并使用外部JSON文件我一直遇到一个问题即JS JSON脚本的社交部分显示值为未定义

<script>
var profiles = {}
window.onload = function () {
    GetProfiles()
}
function GetProfiles(){
    $.getJSON('https://gameremporium.us/image/Profile/profile.json', function(data) {

        var projson = data;
        for(var q in projson){
            jsonpro = projson[q];
            for(var i in jsonpro){
                profile = jsonpro[i];
                if (typeof profile["name"] != "" || typeof profile["name"] != undefined){
                    profiles["name"] += profile.name;
                }
                if (typeof profile["Nick_name"] != "" || typeof profile["Nick_name"] != undefined){
                    profiles["Nick"] += profile.Nick_name;
                }
                if (typeof profile["role"] != "" || typeof profile["role"] != undefined){
                    profiles["role"] += profile.role;
                }
                if (typeof profile["description"] != "" || typeof profile["description"] != undefined){
                    profiles["description"] += profile.description;
                }
                if (typeof profile["image"] != "" || typeof profile["image"] != undefined){
                    profiles["image"] += profile.image_name;
                }
                if (typeof profile["imageBG"] != "" || typeof profile["imageBG"] != undefined){
                    profiles["imageBG"] += profile.imageBG_name;
                }
                if (typeof profile["contact"] != "" || typeof profile["contact"] != undefined){
                    profiles["contact"] += profile.contact_link;
                }
                for(var a in profile){
                    social = profile[a].social_links;
                        for(var a in social){
                            media = social[a]

                            if(media["link_one"].name && media["link_one"].link != ""){
                                profiles.social["link_one"]["name"] += media.name;
                                profiles.social["link_one"]["link"] += media.link;
                            }
                            if(media.name && media.link != ""){
                                profiles.social["link_two"]["name"]  += media.name
                                profiles.social["link_two"]["link"]  += media.link
                            }
                            if(media.name && media.link != ""){
                                profiles.social["link_three"]["name"]  += media.name
                                profiles.social["link_three"]["link"]  += media.link
                            }
                            if(media.name && media.link_four.link != ""){
                                profiles.social["link_four"]["name"]  += media.name
                                profiles.social["link_four"]["link"]  += media.link
                            }
                            if(media.name && media.link != ""){
                                profiles.social["link_five"]["name"]  += media.name
                                profiles.social["link_five"]["link"]  += media.link
                            }
                            if(media.name && media.link != ""){
                                profiles.social["link_six"]["name"] += media.name
                                profiles.social["link_six"]["link"] += media.link
                            }
                        }
                }
                SetProfiles(profiles); 
            }
        };
    })
    };

function SetProfiles(profiles){
    for(var i in profiles){
        profile = profiles[i];
        document.getElementById("profiles").innerHTML = '<div class="card"><img src="'+profile["imageBG"]+'" alt="background-image" class="bg-img"><img src="'+profile["image"]+'" alt="avatar" class="profile-img"><h1>"'+profile["name"]+'"</h1><p class="about-info">"'+profile["description"]+'"</p><a href="'+profile["contact"]+'" class="btn">Contact</a><ul class="social-list" id="social"><li><a href="@" class="social-link"><i class="fa fa-facebook-square"></i></a></li></ul></div>';
    }
}</script>

对于代码中的问题,你提到社交部分的名字值无法获得,但这个问题可能需要更多的上下文和调试信息来确定。如果你需要更多帮助,可以提供更多细节,以便我可以帮助你更好地解决这个问题。

英文:

I was working on setting dynamic profile cards for html in js and using an external json file and i keep running into a problem where the socials part of the js json script displays the values as undefined

&lt;script&gt;var profiles = {} 
window.onload = function () { 
GetProfiles() 
}
function GetProfiles(){
$.getJSON(&#39;https://gameremporium.us/image/Profile/profile.json&#39;, function(data) {
var projson = data;
for(var q in projson){
jsonpro = projson[q];
for(var i in jsonpro){
profile = jsonpro[i];
if (typeof profile[&quot;name&quot;] != &quot;&quot; || typeof profile[&quot;name&quot;] != undefined){
profiles[&quot;name&quot;] += profile.name;
}
if (typeof profile[&quot;Nick_name&quot;] != &quot;&quot; || typeof profile[&quot;Nick_name&quot;] != undefined){
profiles[&quot;Nick&quot;] += profile.Nick_name;
}
if (typeof profile[&quot;role&quot;] != &quot;&quot; || typeof profile[&quot;role&quot;] != undefined){
profiles[&quot;role&quot;] += profile.role;
}
if (typeof profile[&quot;description&quot;] != &quot;&quot; || typeof profile[&quot;description&quot;] != undefined){
profiles[&quot;description&quot;] += profile.description;
}
if (typeof profile[&quot;image&quot;] != &quot;&quot; || typeof profile[&quot;image&quot;] != undefined){
profiles[&quot;image&quot;] += profile.image_name;
}
if (typeof profile[&quot;imageBG&quot;] != &quot;&quot; || typeof profile[&quot;imageBG&quot;] != undefined){
profiles[&quot;imageBG&quot;] += profile.imageBG_name;
}
if (typeof profile[&quot;contact&quot;] != &quot;&quot; || typeof profile[&quot;contact&quot;] != undefined){
profiles[&quot;contact&quot;] += profile.contact_link;
}
for(var a in profile){
social = profile[a].social_links;
for(var a in social){
media = social[a]
if(media[&quot;link_one&quot;].name &amp;&amp; media[&quot;link_one&quot;].link != &quot;&quot;){
profiles.social[&quot;link_one&quot;][&quot;name&quot;] += media.name;
profiles.social[&quot;link_one&quot;][&quot;link&quot;] += media.link;
}
if(media.name &amp;&amp; media.link != &quot;&quot;){
profiles.social[&quot;link_two&quot;][&quot;name&quot;]  += media.name
profiles.social[&quot;link_two&quot;][&quot;link&quot;]  += media.link
}
if(media.name &amp;&amp; media.link != &quot;&quot;){
profiles.social[&quot;link_three&quot;][&quot;name&quot;]  += media.name
profiles.social[&quot;link_three&quot;][&quot;link&quot;]  += media.link
}
if(media.name &amp;&amp; media.link_four.link != &quot;&quot;){
profiles.social[&quot;link_four&quot;][&quot;name&quot;]  += media.name
profiles.social[&quot;link_four&quot;][&quot;link&quot;]  += media.link
}
if(media.name &amp;&amp; media.link != &quot;&quot;){
profiles.social[&quot;link_five&quot;][&quot;name&quot;]  += media.name
profiles.social[&quot;link_five&quot;][&quot;link&quot;]  += media.link
}
if(media.name &amp;&amp; media.link != &quot;&quot;){
profiles.social[&quot;link_six&quot;][&quot;name&quot;] += media.name
profiles.social[&quot;link_six&quot;][&quot;link&quot;] += media.link
}
}
}
SetProfiles(profiles); 
}
};
})
};
function SetProfiles(profiles){
for(var i in profiles){
profile = profiles[i];
document.getElementById(&quot;profiles&quot;).innerHTML = &#39;&lt;div class=&quot;card&quot;&gt;&lt;img src=&quot;&#39;+profile[&quot;imageBG&quot;]+&#39;&quot; alt=&quot;background-image&quot; class=&quot;bg-img&quot;&gt;&lt;img src=&#39;+profile[&quot;image&quot;]+&#39;&quot; alt=&quot;avatar&quot; class=&quot;profile-img&quot;&gt;&lt;h1&gt;&quot;&#39;+profile[&quot;name&quot;]+&#39;&quot;&lt;/h1&gt;&lt;p class=&quot;about-info&quot;&gt;&quot;&#39;+profile[&quot;description&quot;]+&#39;&quot;&lt;/p&gt;&lt;a href=&quot;&#39;+profile[&quot;contact&quot;]+&#39;&quot; class=&quot;btn&quot;&gt;Contact&lt;/a&gt;&lt;ul class=&quot;social-list&quot; id=&quot;social&quot;&gt;&lt;li&gt;&lt;a href=&quot;@&quot; class=&quot;social-link&quot;&gt;&lt;i class=&quot;fa fa-facebook-square&quot;&gt;&lt;/i&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&#39;;
}
}&lt;/script&gt;
THe problem 

code is below and is not getting the name value from the socials nested value in the profiles part of the json file

for(var a in profile){
social += profile[a].social_links;
if(typeof social.link_one.name &amp;&amp; social.social_links.link_one.link != &quot;&quot;){

EDIT: Updated the code now just displays everything back to the underfined

答案1

得分: 0

这是代码的翻译部分:

There's too much to fix in your example code so instead of going over it line by line I'll just provide this alternative code suggestion.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

// kicks off the profile fetching/rendering
makeCards();

// gets the data and invokes addCard for each profile
async function makeCards () {
  const json = await getProfiles();
  const container = document.getElementById('profiles');
  Object.values(json.Profiles).forEach(profile => addCard(profile, container));
}

// makes an individual profile card and adds to parent
function addCard(profile, parent) {
  // bail if we don't have a profile or a parent node
  if (!profile || !parent) {
    return;
  }
  
  // use a template literal instead of string concatenation for the html
  parent.innerHTML += `
  <div class="card">
    ${imgHtml(profile)}
    <h1>${profile.name}</h1>
    <p class="about-info">
      ${contactLinkHtml(profile)}
      <ul class="social-list" id="social">
        <li>
          <a href="@link" class="social-link"><i class="fa facebook-square"></i></a>
        </li>
      </ul>
    </p>
  </div>
  `
}

// use fallback image when image_name isn't present
function imgHtml ({image_name}) {
  return `<img src="${image_name || '//placekitten.com/200'}" alt="avatar" class="profile-img" />`
}

// return html only when contact_link is present
function contactLinkHtml ({contact_link}) {
  return !contact_link ? '' : `<a href="${contact_link}" class="btn">Contact</a>`
}

// ------ the rest is just hand-waving data stuff --------- //

// simulate the fetch request
async function getProfiles() {
  return new Promise((resolve) => {
    setTimeout(resolve(json(), 500));
  })
}

// sample data
function json() {
  return {
    "Profiles": {
      "profile 1": {
        "name": "LoneOxi",
        "Nick_name": "",
        "image_name": "",
        "imageBG_name": "",
        "contact_link": "",
        "description": "",
        "role": "",
        "social_links": {
          "link_one": {
            "name": "",
            "link": ""
          },
          "link_two": {
            "name": "",
            "link": ""
          },
          "link_three": {
            "name": "",
            "link": ""
          },
          "link_four": {
            "name": "",
            "link": ""
          },
          "link_five": {
            "name": "",
            "link": ""
          },
          "link_six": {
            "name": "",
            "link": ""
          },
          "link_seven": {
            "name": "",
            "link": ""
          }
        }
      },
      "profile 2": {
        "name": "Lonnie Gibson",
        "Nick_name": "Quentin",
        "image_name": "//placekitten.com/201",
        "imageBG_name": "LonnieGBG.jpg",
        "contact_link": "",
        "description": "",
        "role": "",
        "social_links": {
          "link_one": {
            "name": "",
            "link": ""
          },
          "link_two": {
            "name": "",
            "link": ""
          },
          "link_three": {
            "name": "",
            "link": ""
          },
          "link_four": {
            "name": "",
            "link": ""
          },
          "link_five": {
            "name": "",
            "link": ""
          },
          "link_six": {
            "name": "",
            "link": ""
          },
          "link_seven": {
            "name": "",
            "link": ""
          }
        }
      }
    }
  }
}

<!-- language: lang-css -->

:root {
  font-family: sans-serif;
}

ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

#profiles {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

.card {
  border-radius: 8px;
  box-shadow: 4px 4px 8px #00000033;
  width: 200px;
  padding: .5rem;
}

.profile-img {
  width: 100px;
  aspect-ratio: 1;
  border-radius: 4px;
}

<!-- language: lang-html -->

<div id="profiles"></div>

<!-- end snippet -->

希望这有帮助!如果你需要进一步的翻译,请告诉我。

英文:

There's too much to fix in your example code so instead of going over it line by line I'll just provide this alternative code suggestion.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

// kicks off the profile fetching/rendering
makeCards();
// gets the data and invokes addCard for each profile
async function makeCards () {
const json = await getProfiles();
const container = document.getElementById(&#39;profiles&#39;);
Object.values(json.Profiles).forEach(profile =&gt; addCard(profile, container));
}
// makes an individual profile card and adds to parent
function addCard(profile, parent) {
// bail if we don&#39;t have a profile or a parent node
if (!profile || !parent) {
return;
}
// use a template literal instead of string concatenation for the html
parent.innerHTML += `
&lt;div class=&quot;card&quot;&gt;
${imgHtml(profile)}
&lt;h1&gt;${profile.name}&lt;/h1&gt;
&lt;p class=&quot;about-info&quot;&gt;
${contactLinkHtml(profile)}
&lt;ul class=&quot;social-list&quot; id=&quot;social&quot;&gt;
&lt;li&gt;
&lt;a href=&quot;@&quot; class=&quot;social-link&gt;&lt;i class=&quot;fa facebook-square&quot;&gt;&lt;/i&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
&lt;/div&gt;
`
}
// use fallback image when image_name isn&#39;t present
function imgHtml ({image_name}) {
return `&lt;img src=&quot;${image_name || &#39;//placekitten.com/200&#39;}&quot; alt=&quot;avatar&quot; class=&quot;profile-img&quot; /&gt;`
}
// return html only when contact_link is present
function contactLinkHtml ({contact_link}) {
return !contact_link ? &#39;&#39; : `&lt;a href=&quot;${contact_link}&quot; class=&quot;btn&quot;&gt;Contact&lt;/a&gt;`
}

// ------ the rest is just hand-waving data stuff --------- //

// simulate the fetch request
async function getProfiles() {
return new Promise((resolve) =&gt; {
setTimeout(resolve(json(), 500));
})
}
// sample data
function json() {
return {
&quot;Profiles&quot;: {
&quot;profile 1&quot;: {
&quot;name&quot;: &quot;LoneOxi&quot;,
&quot;Nick_name&quot;: &quot;&quot;,
&quot;image_name&quot;: &quot;&quot;,
&quot;imageBG_name&quot;: &quot;&quot;,
&quot;contact_link&quot;: &quot;&quot;,
&quot;description&quot;: &quot;&quot;,
&quot;role&quot;: &quot;&quot;,
&quot;social_links&quot;: {
&quot;link_one&quot;: {
&quot;name&quot;: &quot;&quot;,
&quot;link&quot;: &quot;&quot;
},
&quot;link_two&quot;: {
&quot;name&quot;: &quot;&quot;,
&quot;link&quot;: &quot;&quot;
},
&quot;link_three&quot;: {
&quot;name&quot;: &quot;&quot;,
&quot;link&quot;: &quot;&quot;
},
&quot;link_four&quot;: {
&quot;name&quot;: &quot;&quot;,
&quot;link&quot;: &quot;&quot;
},
&quot;link_five&quot;: {
&quot;name&quot;: &quot;&quot;,
&quot;link&quot;: &quot;&quot;
},
&quot;link_six&quot;: {
&quot;name&quot;: &quot;&quot;,
&quot;link&quot;: &quot;&quot;
},
&quot;link_seven&quot;: {
&quot;name&quot;: &quot;&quot;,
&quot;link&quot;: &quot;&quot;
}
}
},
&quot;profile 2&quot;: {
&quot;name&quot;: &quot;Lonnie Gibson&quot;,
&quot;Nick_name&quot;: &quot;Quentin&quot;,
&quot;image_name&quot;: &quot;//placekitten.com/201&quot;,
&quot;imageBG_name&quot;: &quot;LonnieGBG.jpg&quot;,
&quot;contact_link&quot;: &quot;&quot;,
&quot;description&quot;: &quot;&quot;,
&quot;role&quot;: &quot;&quot;,
&quot;social_links&quot;: {
&quot;link_one&quot;: {
&quot;name&quot;: &quot;&quot;,
&quot;link&quot;: &quot;&quot;
},
&quot;link_two&quot;: {
&quot;name&quot;: &quot;&quot;,
&quot;link&quot;: &quot;&quot;
},
&quot;link_three&quot;: {
&quot;name&quot;: &quot;&quot;,
&quot;link&quot;: &quot;&quot;
},
&quot;link_four&quot;: {
&quot;name&quot;: &quot;&quot;,
&quot;link&quot;: &quot;&quot;
},
&quot;link_five&quot;: {
&quot;name&quot;: &quot;&quot;,
&quot;link&quot;: &quot;&quot;
},
&quot;link_six&quot;: {
&quot;name&quot;: &quot;&quot;,
&quot;link&quot;: &quot;&quot;
},
&quot;link_seven&quot;: {
&quot;name&quot;: &quot;&quot;,
&quot;link&quot;: &quot;&quot;
}
}
}
}
}
}

<!-- language: lang-css -->

:root {
font-family: sans-serif;
}
ul {
list-style: none;
margin: 0;
padding: 0;
}
#profiles {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
.card {
border-radius: 8px;
box-shadow: 4px 4px 8px #00000033;
width: 200px;
padding: .5rem;
}
.profile-img {
width: 100px;
aspect-ratio: 1;
border-radius: 4px;
}

<!-- language: lang-html -->

&lt;div id=&quot;profiles&quot;&gt;&lt;/div&gt;

<!-- end snippet -->

Update:

I'd strongly recommend you use arrays for lists of items instead of naming each one, e.g. profile 1, profile 2.

Your list of profiles could look like this for example. (I've omitted some of the profile properties in the interest of brevity and readability.)

{
  &quot;profiles&quot;: [
    {
      &quot;name&quot;: &quot;LoneOxi&quot;,
      &quot;nickname&quot;: &quot;&quot;,
      &quot;imageUrl&quot;: &quot;&quot;,
    },
    {
      &quot;name&quot;: &quot;Lonnie Gibson&quot;,
      &quot;nickname&quot;: &quot;Quentin&quot;,
      &quot;imageUrl&quot;: &quot;//placekitten.com/201&quot;
    }
  ]
}

In addition to eliminating noise and complexity in the json, you can use the array iteration methods like map, forEach, for...of, etc. directly.

obj.Profiles.forEach(profile =&gt; console.log(profile.name))

Same for link_one, link_two. There's no point in naming them this way. I'd recommend you either use the name as the key:

{
  &quot;social_links&quot;: {
    &quot;facebook&quot;: &quot;https://...&quot;,
    &quot;twitter&quot;: &quot;https://...&quot;,
    &quot;instagram&quot;: &quot;https://....&quot;
  }
}

You could iterate these using a for...in loop, or via Object.entries:

for(const name in social_links) {
  const url = social_links[name];
  // do stuff with name and url
}

Object.entries(social_links).forEach(([name, url]) =&gt; {
  // do stuff with name and url
});

Or just use an array of the objects you're already using:

{
  &quot;social_links&quot;: [
    {
      &quot;name&quot;: &quot;facebook&quot;,
      &quot;link&quot;: &quot;https://...&quot;
    },
    {
      &quot;name&quot;: &quot;twitter&quot;,
      &quot;link&quot;: &quot;https://...&quot;
    },
    {
      &quot;name&quot;: &quot;instagram&quot;,
      &quot;link&quot;: &quot;https://...&quot;
    },
  ]
}
social_links.forEach(item =&gt; {
  // do stuff with item.name, item.link
})

I think it's a good idea to keep the root of the json response as an object to allow for additional metadata or whatever, but taken together your API response might look something more like this.

{
  metadata: {
    lastUpdated: &#39;2023-04-04&#39;
  },
  profiles: [
    {
      name: &quot;Lonnie Gibson&quot;,
      image: &quot;/path/to/avatar.jpg&quot;,
      bgImage: &quot;/path/to/bgImage.jpg&quot;,
      social: [
        {
          name: &#39;facebook&#39;,
          url: &#39;https://facebook.com/...&#39;
        },
        {
          name: &#39;twitter&#39;,
          url: &#39;https://twitter.com/...&#39;
        }
      ]
    },
    {
      name: &quot;Someone Else&quot;,
      image: &quot;/path/to/avatar.jpg&quot;,
      bgImage: &quot;/path/to/bgImage.jpg&quot;,
      social: [
        {
          name: &#39;facebook&#39;,
          url: &#39;https://facebook.com/...&#39;
        },
        {
          name: &#39;twitter&#39;,
          url: &#39;https://twitter.com/...&#39;
        }
      ]
    }
  ]
}

huangapple
  • 本文由 发表于 2023年4月4日 14:01:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/75925949.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定