2017-02-07 22 views
1

Я пытаюсь обновить существующее приложение CF8, чтобы потреблять и загружать массив с результатами недавно обновленного ответа API RESTful с использованием OData.ColdFusion 8: преобразовать ответ OData в массив

Вот код в вопросе ... После извлечения данных из API, который отвечает строка OData JSon, код взрывает на последнюю строку, что inits Петли

<!--- Returned data is in json format so must change to an array. ---> 
<cfset local.result = deserializeJSON(myResult)> 

<!--- Reference the array collection of categories ---> 
<cfset local.collection = local.result> 

<!--- Initialize the output object ---> 
<cfset local.output = arrayNew(1)> 

<!--- Loop over the collection ---> 
<cfloop from="1" to="#arrayLen(local.collection)#" index="local.arrayIndex"> 
... 

Это работает нормально используя предыдущий ответ JSON:

[ 
    { 
    "id": 1, 
    "name": "Blah, blah", 
    } 
] 

Единственное изменение, вносимое является обновленный JSON ответ:

[ 
    { 
    "@odata.context": "string", 
    "value": [ 
     { 
     "id": 1, 
     "name": "Blah, blah" 
     } 
    ] 
    } 
] 

Я уверен, что у меня что-то не хватает, но я никогда не работал над CF, так что здесь новая территория.

Мысли?

Спасибо!

ОБНОВЛЕНИЕ: Извините, если не указать более подробно. Вот как приложение в настоящее время использует ответ:

<!--- Loop over the collection ---> 
<cfloop from="1" to="#arrayLen(local.collection)#" index="local.arrayIndex"> 

    <!--- Create a reference to the array element ---> 
    <cfset local.objectInstance = local.collection[local.arrayIndex]> 

    <!--- Create a new object reference ---> 
    <cfset local.thisObject = structNew()> 

    <!--- Seed the object properties ---> 
    <cfset local.thisObject.categoryId = local.objectInstance.id> 
    <cfset local.thisObject.categoryName = local.objectInstance.name> 

    <!--- Place the new object in the collection array ---> 
    <cfset arrayAppend(local.output, duplicate(local.thisObject))> 

</cfloop> 

А вот ошибка я получаю:

Error Occurred While Processing Request 
Object of type class coldfusion.runtime.Struct cannot be used as an array 

The error occurred in <path to file> line 97 

«Линия 97» является начать цикл доступных в обновлении выше:

Я попытался использовать подход «newJSON», предложенный Мигелем (спасибо вам большое за это!), Но, к сожалению, я столкнулся с той же ошибкой.

Еще раз спасибо! -Rich

+0

FWIW, выше [отлично работает с CF10] (http://trycf.com/gist/fc4a542847ab47be6f8362539488924a/acf2016?theme=monokai). (Хотя CF8 может не иметь одинаковой функциональности). * RE: Взорвался на последней строке * Взорвался как? Вы получаете сообщение об ошибке? Если да, можете ли вы [изменить свой вопрос] (http://stackoverflow.com/posts/42102210/edit), чтобы включить его? – Leigh

+0

Спасибо, @Leigh! Это одна из тех ситуаций, когда у меня нет контроля над архитектурой, и в ближайшие пару лет вам грозит полная переписывание. Я владею API, который раскрывает новые данные, и взял на себя роль «поддержки» для обновления клиентов ... это последнее. Я обновил свою начальную запись с ошибкой, которую я могу уловить, HTH! – richwallace

+0

Я согласен с Miguel-F, вы должны делать что-то другое или ошибка вызвана немного другим кодом. Если вы добавите cfloop в мой предыдущий пример, он выдает ошибку на * local.objectInstance *, потому что этот объект является массивом, а не структурой. Таким образом, вы получаете ошибку, потому что * local.objectInstance.id * не существует. Попробуйте его обновленный пример. – Leigh

ответ

2

Update после пользователь отправил больше информации

Если вы все еще получаете сообщение об ошибке, то вы сделали что-то неправильно. Вы должны изменить способ ссылки на новый объект данных JSON. Я создал новый Gist, используя обновленный код, который вы предоставили, чтобы вы могли увидеть, как это работает. TryCF Gist 2

В принципе, код в вашем <cfloop> должен выглядеть следующим образом. Опять же, обратите внимание, что на самом деле есть два блока <cfloop>. Это связано с тем, что новый формат JSON генерирует массив, содержащий другой массив.

<!--- Loop over the collection ---> 
<cfloop from="1" to="#arrayLen(local.collection)#" index="local.arrayIndex"> 

    <cfloop from="1" to="#arrayLen(local.collection[local.arrayIndex].value)#" index="local.arrayIndex2"> 

     <!--- Create a reference to the array element ---> 
     <cfset local.objectInstance = local.collection[local.arrayIndex].value> 

     <!--- Create a new object reference ---> 
     <cfset local.thisObject = structNew()> 

     <!--- Seed the object properties ---> 
     <cfset local.thisObject.categoryId = local.objectInstance[local.arrayIndex2].id> 
     <cfset local.thisObject.categoryName = local.objectInstance[local.arrayIndex2].name> 

     <!--- Place the new object in the collection array ---> 
     <cfset arrayAppend(local.output, duplicate(local.thisObject))> 

    </cfloop> 

</cfloop> 

Смотрите GIST для получения более подробной информации, но это присваивает local.output массив, как это было раньше. В вашем исходном коде local.objectInstance внутри цикла была структурой. В новом формате JSON local.objectInstance внутри цикла теперь содержит массив структур. Поэтому вам нужно ссылаться на нее как таковую.

enter image description here

Оригинальный ответ перед тем вопрос был обновлен

С обновленной JSON вам нужно обновить, как ваш код ссылается на данные (которые вы не включили в исходное сообщение). Сделав некоторые предположения, я могу показать вам, как ссылаться на данные, используя приведенные вами примеры.

Первый для вашего первоначального примера. Вот какой код, который будет ссылаться и выводить данные для вас. Обратите внимание, что я включил тег <cfdump>. Вы захотите использовать это в ситуациях, подобных этому, где вам нужно см. данные. Функция deserializeJSON() анализирует JSON для вас и создает массив структур ColdFusion.

<cfset oldJSON = '[ { "id": 1, "name": "Blah, blah" } ]'> 

<!--- Returned data is in json format so must change to an array. ---> 
<cfset local.result = deserializeJSON(oldJSON)> 

<!--- Reference the array collection of categories ---> 
<cfset local.collection = local.result> 

<!--- Initialize the output object ---> 
<cfset local.output = arrayNew(1)> 

<cfdump var="#local.result#" label="Old JSON"> 

<!--- Loop over the collection ---> 
<cfoutput> 
<cfloop from="1" to="#arrayLen(local.collection)#" index="local.arrayIndex"> 
    <p>#local.arrayIndex# - #local.collection[local.arrayIndex].id# - #local.collection[local.arrayIndex].name#</p> 
</cfloop> 
</cfoutput> 

Этот код дает этот вывод:

enter image description here

Вот пример обновленного кода, необходимого для получения тех же значений из нового формата JSON. Обратите внимание, что я добавил еще cfloop для ссылки на данные, потому что теперь есть два массива.

<cfset newJSON = '[ { "@odata.context": "string", "value": [ { "id": 1, "name": "Blah, blah" } ] } ]'> 
<!--- Returned data is in json format so must change to an array. ---> 
<cfset local.result = deserializeJSON(newJSON)> 

<!--- Reference the array collection of categories ---> 
<cfset local.collection = local.result> 

<!--- Initialize the output object ---> 
<cfset local.output = arrayNew(1)> 

<cfdump var="#local.result#" label="New JSON"> 

<!--- Loop over the collection ---> 
<cfoutput> 
<cfloop from="1" to="#arrayLen(local.collection)#" index="local.arrayIndex"> 
    <cfloop from="1" to="#arrayLen(local.collection[local.arrayIndex].value)#" index="local.arrayIndex2"> 
     <p>#local.arrayIndex# - #local.arrayIndex2# - #local.collection[local.arrayIndex].value[local.arrayIndex2].id# - #local.collection[local.arrayIndex].value[local.arrayIndex2].name#</p> 
    </cfloop> 
</cfloop> 
</cfoutput> 

Этот код дает этот вывод:

enter image description here

Я создал суть со всеми этим кодом, который вы можете играть вокруг с - TryCF Gist 1

 Смежные вопросы

  • Нет связанных вопросов^_^