What works:
In Breeze I can execute this query:
Q1
breeze.EntityQuery.from('accounts').where('id', 'eq', account_id)
which results in this request:
R1
http://localhost:8000/odata/findash.svc/accounts
?$filter=id eq 'NTE5M2UxMzQzMmY3MDAxYzE1MDAwMDAx'
which returns the correct data except that the transactions property looks like this:
transactions: {
__deferred: {
uri: "http://localhost:8000/odata/findash.svc/accounts('NTE5M2UxMzQzMmY3MDAxYzE1MDAwMDAx')/transactions"
}
}
I tried hitting the URI at transactions.__deferred.uri in a browser
R1.1
http://localhost:8000/odata/findash.svc/
accounts('NTE5M2UxMzQzMmY3MDAxYzE1MDAwMDAx')/transactions
and it does respond with the transactions I would expect.
What doesn't work:
To try and get that transaction list through Breeze I alter the above query with an expand clause like so:
Q2
breeze.EntityQuery.from('accounts')
.where('id', 'eq', account_id).expand('transactions')
which results in this request:
R2
http://localhost:8000/odata/findash.svc/accounts
?$filter=id eq 'NTE5M2UxMzQzMmY3MDAxYzE1MDAwMDAx'&$expand=transactions
which generates a 500 error.
I also tried this Breeze query:
Q3
breeze.EntityQuery.from('transactions')
.expand('account').where('account.id', 'eq', account_id)
which also generates a 500 error.
What I need to know:
I'm trying to rule out Breeze before I dive into the OData service which is built on Node+MongoDB+JayData.
The only difference between R1 and R2 above is the addition of &$expand=transactions. R1 works and R2 results in a 500 error. If R2 is a valid OData request then I need to focus my troubleshooting efforts on my JayData implimentation. The trouble for me is that I'm new to Breeze, OData & JayData, so I'm having trouble narrowing my search.
For reference, my JayData context.js is here:
$data.Class.define("$findash.Types.Account", $data.Entity, null, {
id: { type: "id", key: true, computed: true },
name: { type: "string" },
status: { type: "string" },
notes: { type: "string" },
transactions: { type: "Array", elementType: "$findash.Types.Transaction", inverseProperty: "account" }
}, null);
$data.Class.define("$findash.Types.Transaction", $data.Entity, null, {
id: { type: "id", key: true, computed: true },
account: { type: "$findash.Types.Account", inverseProperty: "transactions" },
payee: { type: "string" },
memo: { type: "string" },
amount: { type: "int" }
}, null);
$data.Class.define("$findash.Types.FinanceContext", $data.EntityContext, null, {
accounts: { type: $data.EntitySet, elementType: $findash.Types.Account },
transactions: { type: $data.EntitySet, elementType: $findash.Types.Transaction }
}, null);
$findash.Types.FinanceContext.generateTestData = function (context, callBack) {
context.accounts.add(new $findash.Types.Account({
name: 'Checking',
status: 'Active',
notes: '<p>Notes lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus mauris quam, elementum in tincidunt id, mollis eget urna. Nulla fermentum est id risus venenatis malesuada. Quisque sed ipsum at nisl malesuada dictum vitae nec libero.</p><p>Aenean consectetur, purus eu semper feugiat, purus lacus semper nibh, at luctus ipsum metus non justo. Donec justo mi, rutrum a scelerisque sed, feugiat vel quam. Etiam justo nisi, vehicula ac congue vitae, ultricies non quam. Aliquam a velit in mauris luctus elementum. Praesent sollicitudin quam mattis velit sodales vitae feugiat felis volutpat.</p>',
transactions: [
new $findash.Types.Transaction({
payee: 'Shell Gas',
memo: 'Checkcard Transaction',
amount: -3500
}),
new $findash.Types.Transaction({
payee: 'Kroger',
memo: 'Checkcard Transaction',
amount: -9000
}),
new $findash.Types.Transaction({
payee: 'Papa Murphy\'s',
memo: 'Checkcard Transaction',
amount: -1500
})
]
}));
context.accounts.add(new $findash.Types.Account({
name: 'Savings'
}));
context.accounts.add(new $findash.Types.Account({
name: 'Power Company'
}));
context.accounts.add(new $findash.Types.Account({
name: 'Gas Company'
}));
context.accounts.add(new $findash.Types.Account({
name: 'Cable Company'
}));
context.accounts.add(new $findash.Types.Account({
name: 'Water Company'
}));
context.accounts.add(new $findash.Types.Account({
name: 'Trash Service'
}));
context.saveChanges(function (count) {
if (callBack) {
callBack(count);
}
});
};
module.exports = exports = $findash.Types.FinanceContext;
Can you post the code for the relevant sections of the server side model? This looks like a problem on the server side with the model definition, or how it is exposed thru OData.
The real test of this is to try hitting the OData service without Breeze involved at all. I'm guessing that you will get the same error. If not, then this is a Breeze error. If so, then you need to review your OData service.
Related
I am trying to add all elements to a list, Here is my code the code below will run in dart pad.
void main() {
mydates();
}
class Event {
const Event(this.date, this.title, this.description);
final DateTime date;
final String title;
final String description;
#override
String toString() => title;
}
List<Event> eventList = [
Event(DateTime(2021, 1, 1), "Buy milk",
"Lorem ipsum dolor sit amet, consectetur adipiscingelit. Pellentesque sem"),
Event(DateTime(2021, 1, 1), "Go to gym",
"Duis congue enim ut justo interdum, id porta turpisvarius"),
Event(DateTime(2021, 1, 2), "Running",
"Fusce in varius lorem. Praesent accumsan metus at semfaucibus"),
];
//Function
mydates() {
var eventDayMap = <DateTime, List<Event>>{};
for (var event in eventList) {
print(event.date); // Prints each element in the List<Event>
print(event.title);
print(event.description);
// Adding them to the eventDayMap
// Creates a new list
// Adds only the date and title
(eventDayMap[event.date] ??= []).add(event);
}
print(eventDayMap);
//print(eventDayMap.runtimeType);
return eventDayMap;
}
What is returned is this
{2021-01-01 00:00:00.000: [Buy milk, Go to gym], 2021-01-02 00:00:00.000: [Running]}
What I'm trying to achieve is the {date, title, description} and there can be many title and descriptions for one date.
{2021-01-01 00:00:00.000: [Buy milk, Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque sem ],
[Go to gym, Duis congue enim ut justo interdum, id porta turpis varius],
2021-01-02 00:00:00.000: [Running, Fusce in varius lorem. Praesent accumsan metus at sem faucibus]}
So I can have a title and a description returned.
Thanks for any guidance.
What your problem is depends on what your goal is.
If you want to create a valid JSON map, you will want to represent each element by a list. That doesn't appear to be the case since your keys are DateTime objects, not strings.
If you just want to be able to print the events, for debugging, then your problem is the String toString() => title; declaration.
Your map is fine, it maps from dates to Event objects. That's what you'll want.
Then you try to print that map, which calls toString on each value, which only returns the title string.
That only matters if you actually print the map, which you shouldn't be doing (except for debugging).
If you change toString to
String toString() => "[$title, $description]";
you'll likely get what it appears you're looking for.
I think I worked it out after a long time trying to do it my self it comes to me after posting it here.
I needed to return a List instead of a single event.
void main() {
mydates();
}
class Event {
const Event(this.date, this.title /*, this.description*/);
final DateTime date;
final List title;
//final String description;
//#override
//String toString() => title;
}
List<Event> eventList = [
Event(DateTime(2021, 1, 1), [
"Buy milk",
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque sem"
]),
Event(DateTime(2021, 1, 1), [
"Go to gym",
"Duis congue enim ut justo interdum, id porta turpis varius"
]),
Event(DateTime(2021, 1, 2), [
"Running",
"Fusce in varius lorem. Praesent accumsan metus at sem faucibus"
]),
];
//Function
mydates() {
var eventDayMap = <DateTime, List<Event>>{};
for (var event in eventList) {
print(event.date); // Prints each element in the List<Event>
print(event.title);
//print(event.description);
// Adding them to the eventDayMap
// Creates a new list
// Adds only the date and title
(eventDayMap[event.date] ??= []).add(event);
}
print(eventDayMap);
//print(eventDayMap.runtimeType);
return eventDayMap;
}
Now it returns
2021-01-01 00:00:00.000
[Buy milk, Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque sem]
2021-01-01 00:00:00.000
[Go to gym, Duis congue enim ut justo interdum, id porta turpis varius]
2021-01-02 00:00:00.000
[Running, Fusce in varius lorem. Praesent accumsan metus at sem faucibus]
Not exactly what I was looking for but it might be a better solution.
I have this json which I converted to a POJO
The JSON converted to POJO file
[
{
"postId": 81,
"id": 401,
"name": "cum voluptate sint voluptas veritatis",
"email": "Vella.Mayer#colten.net",
"body": "sit delectus recusandae qui\net cupiditate sed ipsum culpa et fugiat ab\nillo dignissimos quo est repellat dolorum neque\nvoluptates sed sapiente ab aut rerum enim sint voluptatum"
},
{
"postId": 81,
"id": 403,
"name": "cum voluptate sint voluptas veritatis",
"email": "Vella.Mayer#colten.net",
"body": "sit delectus recusandae qui\net cupiditate sed ipsum culpa et fugiat ab\nillo dignissimos quo est repellat dolorum neque\nvoluptates sed sapiente ab aut rerum enim sint voluptatum"
}
]
This is the POJO class I converted it into
public class TodoItem{
private int id;
private boolean completed;
private String title;
private int userId;
I tried using todo to validate the response that it of the type of the class but always get this error.
Todo todo = response.getBody().as(Todo.class);
Assert.assertTrue(response.statusCode() == 200);
Error
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `io.christdoes.pojo.todo.Todo` out of START_ARRAY token
at [Source: (String)"[
There are 2 things you did wrong:
The POJO that you're matching
The way you map (Array cannot map to one single object)
It would be
List<TodoItem> todoItems = response.as(new TypeRef<>() {});
POJO (I use lombok to generate getters/setters)
import lombok.Data;
#Data
public class TodoItem{
private int postId;
private int id;
private String name;
private String email;
private String body;
}
I have created these typealias in my project
typealias JSON = [String: AnyObject]
typealias JSONArray = [JSON]
I'm testing an JSON API Client using JSONPlaceholder and getting two different JSON responses.
Response 1 (JSON)
{
userId: 1,
id: 1,
title: "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
body: "quia et suscipit suscipit recusandae consequuntur expedita et cum reprehenderit molestiae ut ut quas totam nostrum rerum est autem sunt rem eveniet architecto"
}
Response 2 (Array of JSON)
[
{
userId: 1,
id: 1,
title: "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
body: "quia et suscipit suscipit recusandae consequuntur expedita et cum reprehenderit molestiae ut ut quas totam nostrum rerum est autem sunt rem eveniet architecto"
},
{
userId: 1,
id: 2,
title: "qui est esse",
body: "est rerum tempore vitae sequi sint nihil reprehenderit dolor beatae ea dolores neque fugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis qui aperiam non debitis possimus qui neque nisi nulla"
},
...
]
In order to create my code as generic as possible, I'm using a protocol approach. Everything works fine but I have a small issue parsing the json response.
// JSONResource is a protocol
extension JSONResource {
func handleResponse(_ data: Data?, response: URLResponse?, error: NSError?) -> WebServiceResult<Response> {
let parsedData = try! JSONSerialization.jsonObject(with: data, options: .allowFragments)
do {
if let json = parsedData as? JSON {
let parsedResponse = try Response(json: json)
return .success(parsedResponse)
}
if let jsonArray = parsedData as? JSONArray {
let parsedResponse = try Response(jsonArray: jsonArray)
return .success(parsedResponse)
}
} catch let error as NSError {
return .failure(error)
}
}
}
The Response is created using a protocol too
protocol JSONServiceResponse: WebServiceResponse {
init(json: JSON) throws
init(jsonArray: JSONArray) throws
}
My problem is my code seems redundant because I have to handle JSON an JSONArray types but I'll only know that when I'm creating the type who implements the protocol.
Is there a different way to handle the JSON and JSONArray responses from the server in order to use a unique init(json: JSON) ?
Thanks
I am try to convert this JSON data into Dictionary, but I don't know how the data will be structured in this JSON. I think my code for detect JSON struct thats wrong.
JSON Response
[
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
},
{
"userId": 2,
"id": 2,
"title": "et ea vero quia laudantium autem",
"body": "delectus reiciendis molestiae occaecati non minima eveniet qui voluptatibus\naccusamus in eum beatae sit\nvel qui neque voluptates ut commodi qui incidunt\nut animi commodi"
}
]
Thats my code :
enum postResult {
case Success([Post]) //return array of post
case Failure(ErrorType)
//
func postsFromJSONData(data:NSData)->PhotosResult{
do {
let jsonObject : AnyObject = try NSJSONSerialization.JSONObjectWithData(data,options:[])
guard let jsonDictionary = jsonObject as? [NSObject:AnyObject],
postsArray = ["userId"] as? [[String:AnyObject]] else {
return.Failure(InvalidError.InvalidJSONData)
}
var finalPosts = [post]()
return.Success(finalPosts)
}
catch let error {
return.Failure(error)
}
}
}
Your response is Array not Dictionary, so you need to access object from Array also your userId key contains number as value not Array/Dictionary.
let jsonObject = tryNSJSONSerialization.JSONObjectWithData(data,options:[]) as! [[String: AnyObject]]
if jsonObject.count > 0 {
if let userId = jsonObject[0]["userId"] as? Int {
print(userId)
}
}
I am working on my PHP file and now I get this message.
"Parse error: syntax error, unexpected '<', expecting T_FUNCTION in /home/content/18/9029618/html/wp-content/themes/NewBusiness/includes/aboutus.php on line 8"
Have no idea what is wrong and now my site is down. Here is the code below.
<?php
new Themater_AboutUs();
class Themater_AboutUs
{
var $theme;
var $defaults = array(
'enabled' => 'true',
'hook' => 'main_before',
'title' => 'Welcome to our website. Neque porro quisquam est qui dolorem ipsum dolor.',
'image' => 'about-image.jpg',
'content' => 'Lorem ipsum eu usu assum liberavisse, ut munere praesent complectitur mea. Sit an option maiorum principes. Ne per probo magna idque, est veniam exerci appareat no. Sit at amet propriae intellegebat, natum iusto forensibus duo ut. Pro hinc aperiri fabulas ut, probo tractatos euripidis an vis, ignota oblique. <br /> <br />Ad ius munere soluta deterruisset, quot veri id vim, te vel bonorum ornatus persequeris. Maecenas ornare tortor. Donec sed tellus eget sapien fringilla nonummy. Mauris a ante. Suspendisse quam sem, consequat at, commodo vitae, feugiat in, nunc. Morbi imperdiet augue quis tellus.'
);
function Themater_AboutUs()
{
global $theme;
$this->theme = $theme;
if(is_array($this->theme->options['plugins_options']['aboutus']) ) {
$this->defaults = array_merge($this->defaults, $this->theme->options['plugins_options']['aboutus']);
}
if($this->theme->display('aboutus_enabled') ) {
$this->theme->add_hook($this->defaults['hook'], array(&$this, 'display_aboutus'));
}
if($this->theme->is_admin_user()) {
$this->aboutus_options();
}
}
function display_aboutus()
{
if(is_home()) {
?><div class="span-24 aboutusbox">
<?php
if($this->theme->display('aboutus_image')) {
echo '<img class="aboutusbox-image" src="' . $this->theme->get_option('aboutus_image') . '" />';
}
if($this->theme->display('aboutus_title')) {
echo '<h2 class="aboutusbox-title">' . $this->theme->get_option('aboutus_title') . '</h2>';
}
if($this->theme->display('aboutus_content')) {
echo '<div class="aboutusbox-content">' . $this->theme->get_option('aboutus_content') . '</div>';
}
?></div><?php
}
}
function aboutus_options()
{
$this->theme->admin_option(array('About Us', 14),
'"About Us" section enabled?', 'aboutus_enabled',
'checkbox', $this->defaults['enabled'],
array('display'=>'inline')
);
$this->theme->admin_option('About Us',
'Title', 'aboutus_title',
'text', $this->defaults['title']
);
$this->theme->admin_option('About Us',
'Image', 'aboutus_image',
'imageupload', get_bloginfo('template_directory') . "/images/" . $this->defaults['image'],
array('help' => "Enter the full url. Leave it blank if you don't want to use an image.")
);
$this->theme->admin_option('About Us',
'Content', 'aboutus_content',
'textarea', $this->defaults['content'],
array('style'=>'height: 250px;')
);
}
}
?>
Is that the full file? Is there a <?php at the beginning?
The sample that you have pasted is missing a closing brace } at the end.