未捕获(承诺中)TypeError:listing.owner在尝试提交时未定义



我正在开发一个带有Rails应用程序的JavaScript,当我试图与刚创建的新所有者一起提交新的房产列表表单时,它不会允许我提交表单,只允许我在刷新页面后与选定的新所有者提交表单。当我尝试用新创建的所有者提交新的属性列表时,我的控制台中不断收到一条未捕获(承诺中(类型错误:listing.owner未定义消息。

仅供参考:我不允许在此项目中使用ERB

到目前为止我的代码:这是我用来创建新房产所有者的表格

<form id = "owner_form">
<div>
<label for='name'>Owner Name:</label>
<input type='text' id='name' name='name' placeholder="John Doe" >
</div>
<div>
<label for='phone_number'>Phone Number:</label>
<input type='text' id='phone_number' name='phone_number' placeholder="Phone Number" >
</div>
<div>
<label for='real_estate_agent'>Listing Agent:</label>
<input type='text' id='real_estate_agent' name='real_estate_agent' placeholder="Agent">
</div>
<div>
<input type='submit' id='owner_submit' value='Submit'/>
</div>
</form>

然后,一旦我提交了所有者创建表单,它就会通过GET获取方法在我的属性列表中设置的下拉列表中动态地删除新所有者

<form id = "listing_form">
<div>
<label for='name'>Owner Name:</label>
<select id='owner_id' name='owner_id' >

</select>
</div>
<div>
<label for='address'>Street Address:</label>
<input type='text' id='address' name='address' placeholder="123 Elm Street">
</div>
<div>
<label for='state'>State:</label><br>
<input type='text' id='state' name='state' placeholder="Texas">
</div>
<div>
<label for='sale_price'>Listing Price:</label><br>
<input type='text' id='sale_price' name='sale_price' placeholder="$500,000">
</div>
<div>
<input type='submit' id='prop_submit'  value='Submit'/>
</div>
</form>

然后我将listForm节点附加到addEventListener

listForm.addEventListener('submit',(event) =>{
// event.preventDefault()

const formData = new FormData(event.currentTarget);
fetch(PROPERTIES_URL,{
method: 'POST',
header: {
'Content-Type': 'application/json',
"Accept": "application/json"
},
body: formData
}).then(res => res.json()).then((list_data) => {

let new_listing = renderListing(list_data)
listForm.reset()
listings.append(new_listing)

console.log(list_data)
})
})

这里的问题是,当我提交表单以创建新的属性列表时,我一直收到这个"未捕获(承诺中(类型错误:listing.owner未定义">,这阻止了与新创建的所有者一起创建新的列表。

它引用的代码是:

const showListCard = (listing) => {

return `<p>Address: ${listing.address}</p>
<p>State: ${listing.state}</p>
<p>Sale Price: ${listing.sale_price}</p>
<p>Owner: ${listing.owner.name}</p>`
}


const renderListing = (listing) => {
let listingCard = document.createElement('div')
listingCard.setAttribute('class','card')
listingCard.dataset.id = listing.id
listingCard.innerHTML = showListCard(listing)
//---Delete Button
let deleteBtn = document.createElement('button')
deleteBtn.setAttribute('id','delete')
deleteBtn.innerHTML = 'Delete Listing'
deleteBtn.addEventListener('click', (event)=>{
let listingId = parseInt(event.target.dataset.listingId)
event.target.parentNode.remove()
deleteListing(listingId)
})
listingCard.appendChild(deleteBtn)

return listings.appendChild(listingCard)



}

这里还有后端轨道代码

class Owner < ApplicationRecord
has_many :properties
end
class Property < ApplicationRecord
belongs_to :owner

end
#property listing create action in properties controller
def create

property = Property.create(prop_params)
prop_params[:owner_id] = :owner.id
if property.save
render json: property
else
render json: { error: "Couldn't save"}
end
end
private
def prop_params
params.permit(:id,:address, :state, :sale_price, :owner_id)
end
#owner create action in owners controller
def create

@owner = Owner.create(owner_params)
if @owner.save
render json: @owner
end

end
private 
def owner_params
params.permit(:id,:name,:phone_number,:real_estate_agent)
end

我厌倦了在我的创建操作中为我的后端prop_params[:owner_id]=@owner.id创建关联,但这对我来说一直不起作用。我该怎么办才能解决我上面提到的"Uncaught(in promise(TypeError:listing.owner is undefined"?

更新添加整个属性控制器

class PropertiesController < ApplicationController
before_action :set_owner, only: [:create,:show, :edit, :update, :destroy]
def new
Property.new
end

def index
properties = Property.all
render json: properties
end

def show
property = Property.find(params[:id])
options = {
include: [:owner]
}
render json: property
end
def create
byebug
property = Property.create(prop_params)

if property.save
render json: property
else
render json: { error: "Couldn't save"}
end
end
def destroy
property = Property.find(params[:id])
unless property.nil?
property.destroy
render json: property
else
render json: { error: "Property not found" }, status: 404
end
end
private
def set_owner
@owner = Owner.find(params[:owner_id])
end

def prop_params
params.(:owner).permit(:id,:address, :state, :sale_price, :owner_id)
end
end

因此,如果我没记错的话,您需要告诉控制器它需要首先获取另一个对象。在您的情况下,它需要在返回响应之前先获取所有者。

在您的属性控制器中,文件需要以以下内容开头:

class PropertiesController < ApplicationController
before_action :set_owner, only: [:show, :edit, :update, :destroy]

这让控制器知道,在为:show、:edit、:update或:delete发回响应之前,它需要首先执行set_owner方法。你可以调整数组中的值,使它只在你需要的时候调用函数。在你的情况下,它可能只是你想要的:show和:edit。

在靠近文件底部的私有方法中,您需要类似以下内容:

private
# Use callbacks to share common setup or constraints between actions.
def set_owner
@owner = Owner.find(params[:owner_id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def prop_params
params.require(:owner).permit(:id, :address, :state, :sale_price)
end

我希望仅此而已?如果它仍然不起作用,请发表评论,我正在努力重新熟悉这一切!Ruby Rails绝对不是我最喜欢的web框架

最新更新