Cannot get JSON response from API - api

I have a RESTful API web service. I'm programming a simple pure Javascript client app to interact with the APIs. I also use Knockout framework. My Javscript code:
self.movies = ko.observableArray();
$.get(self.moviessURI, function(data){
var obj = JSON.parse(data);
for (var i=0; i < obj.movies.length; i++) {
self.movies.push(obj.movies[i]);
}
}, "json");
My HTML code:
<table class="table table-striped">
<tr><td><b>Title</b></td><td><b>VideoID</b></td></tr>
<!-- ko foreach: movies -->
<tr>
<td><p><b data-bind="text: title"></b></p></td><td><p data-bind="text: videoId"></p></td>
</tr>
<!-- /ko -->
</table>
After running, I have a request status 200 on the web service, but my client app does not display anything. I also used Postman to test the API and its working.
Where did I do wrong? Thanks for any help!

Related

ReactJS.net unable to debug

I've created a small app using ReactJS.Net and ASP.NET 5. If I render a component serverside using #Html.React and tie that to the MVC
#using System.Threading.Tasks
#using React.AspNet
#model Models.DashboardViewModel
#Html.React("MessageBoard", new
{
recentPosts = Model.RecentPosts
})
messageBoard.jsx
"use strict";
var MessageBoard = React.createClass({
render: function(){
return (<table className="table forum table-striped">
<thead>
<tr>
<th className="cell-stat"></th>
<th>Topic</th>
<th className="cell-stat text-center hidden-xs hidden-sm">Replies</th>
<th className="cell-stat-2x hidden-xs hidden-sm">Last Post</th>
</tr>
</thead>
<tbody>
{this.props.recentPosts.map(function(boardPost){
return <BoardPostRow post={boardPost}/>;
}, this)}
</tbody>
</table>)
}
});
This all works great. The problem is that when I go to sources, there is no .js file so I have no way to debug. This is probably ok for some simple read-only elements. But now I want to render some interactive elements that contain state, a form for creating a new Post to the "message board". Here's the code in the same *.cshtml file.
<div id="newPost"></div>
#section scripts
{
<script src="#Url.Content("~/scripts/Components/Board/boardPostForm.jsx")"></script>
<script src="#Url.Content("~/scripts/Components/Common/textInput.jsx")"></script>
<script>React.render(BoardPostForm({}), document.getElementById("newPost"))</script>
#Html.ReactInitJavaScript()
}
The error I get in the console is:
Uncaught SyntaxError: Unexpected token <
textInput.jsx:19 Uncaught SyntaxError: Unexpected token <
(index):69 Uncaught ReferenceError: BoardPostForm is not defined(anonymous function) # (index):69
(index):70 [.NET] Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of MessageBoard. See http://fb.me/react-warning-keys for more information.
(index):71 [.NET] Warning: Unknown DOM property class. Did you mean className?
(index):71 Uncaught ReferenceError: MessageBoard is not defined
It seems an error trying to read the .jsx, because it takes me to the render function when I click on the error. What am I missing here? Maybe I need to do the jsx->js conversion as part of my build process (I am using Gulp) instead of relying on ReactJS.NET?
What happens if you hit /scripts/Components/Board/boardPostForm.jsx in your web browser? It should show the compiled JSX and have some ReactJS.NET info at the top of the file. If it doesn't, make sure the *.jsx handler is configured in your Web.config. It should look something like this:
<add name="ReactJsx" verb="GET" path="*.jsx" type="React.Web.JsxHandlerFactory, React.Web" preCondition="integratedMode" />
What am I missing here? Maybe I need to do the jsx->js conversion as part of my build process (I am using Gulp) instead of relying on ReactJS.NET?
You can use Gulp if you like, up to you. I have a sample here that uses Webpack for bundling, and ReactJS.NET for server-side rendering: https://github.com/reactjs/React.NET/tree/master/src/React.Sample.Webpack

IBM MobileFirst SQL Adapter

I want to connect my IBM MobileFirst apps to my database,
I use wampserver (localhost),
username = "root", password ="...", database name = "mydatabase".
In my MobileFirst project, I created a SQL adapter "myAdapter".
Inside the myAdapter.xml, this is the code:
<connectivity>
<connectionPolicy xsi:type="sql:SQLConnectionPolicy">
<!-- Example for using a JNDI data source, replace with actual data source name -->
<!-- <dataSourceJNDIName>java:/data-source-jndi-name</dataSourceJNDIName> -->
<!-- Example for using MySQL connector, do not forget to put the MySQL connector library in the project's lib folder -->
<dataSourceDefinition>
<driverClass>com.mysql.jdbc.Driver</driverClass>
<url>jdbc:mysql://localhost:3306/mydatabase</url>
<user>root</user>
<password></password>
</dataSourceDefinition>
</connectionPolicy>
</connectivity>
<!-- Replace this with appropriate procedures -->
<procedure name="insertMyTable1"/>
Below is myAdapter-impl.js file
var insertMyTable = WL.Server.createSQLStatement(
"IESERT INTO mytable" +
"VALUES (? , ? , ?);");
function insertMyTable1(id, name, age){
return WL.Server.invokeSQLStatement({
preparedStatement : insertMyTable,
parameters : [id, name, age]
});
}
//--------------------------------------
in one of my pages, I have a addData.html file, below is the code:
<html>
<script>
function insertData(){
var id = document.getElementById("id").value;
var name = document.getElementById("name").value;
var age = parseInt(document.getElementById("age").value);
WL.Client.invokeProcedure({
adapter : "myAdapter",
procedure : "insertMyTable1",
parameters : [ id, name, age ]
});
}
</script>
<body>
<form action="javascript:insertData();">
<table align="center">
<tr>
<td>Id : </td>
<td><input type="text" id="id"></td>
</tr>
<tr>
<td>Name : </td>
<td><input type="text" id="name"></td>
</tr>
<tr>
<td>Age : </td>
<td><input type="text" id="age"></td>
</tr>
<tr>
<td colspan="2" align="center">
<button type="submit" style="width:100px;">Add</button>
</td>
</tr>
</table>
</form>
</body>
</html>
But I fail to insert the data into mydatabase->mytable, anyone know why ??
error log (in my addData.html)
Uncaught ReferenceError: WL is not defined
This question is completely unrelated to your SQL adapter.
The problem here is that you have used a href to navigate to another HTML file. By doing so you have exited the scope, or context, of the MFP framework, which is why you are unable to use MFP API methods such as WL.Client.invokeProcedure.
A MFP Hybrid application is a Single Page Application. In the app's index.html there are references to the MFP JavaScript framework in order to load it... Without these, things will break.
In order to use multiple "pages" in your application, see the following tutorial:
Building a multi-page application
You must never actually navigate away from the context of the framework, so operations such as a href are not allowed.
If you want to separate your "pages" to separate HTML files, you can see this example project using jQuery Mobile. Other UI frameworks such as Dojo also provide their own implementation for multi-page support which you could use in your MFP application.
Related questions: https://stackoverflow.com/search?q=%5Bworklight%5D+multipage+is%3Aquestion

Why is a signaling server needed for WebRTC?

WebRTC is a protocol that defines the transport method for media data between peer-to-peer. Understood. Also it works on top of RTP/UDP. This also understood.
While getting the discussion about signalling server it is mentioned that it is required to do compatibility check/channel initiation... and so on works.
My Question is: having said above,
1) Does it mean that a signaling server is mandatory?
2) Does WebRTC not have the intelligence to talk directly to the other peer without a signaling server?
3) Every article related with WebRTC starts with the statement that "It is between browser to browser communication?", does it mean, WebRTC can not be used between a) Embedded device with camera [Without Browser], b) Browser somewhere else.
4) Also, what is the gain if WebRTC is used compared to the legacy way of streaming into the browser? [I honestly don't know the legacy way].
I know it is a theoretical question. Though, i see this kind of question probably in different context floats around in the internet. Hope this question gives some architecture-level answers. Thanks.
WebRTC doesn't solve discovery (nor should it).
WebRTC knows how to talk directly to another peer without a signaling server, but it doesn't know how to discover another peer. Discovery is an inherent problem, so I'm a bit baffled that people expect WebRTC to solve it for them.
Think about it: How are you going to call me? How are you going to direct your computer to initiate contact with me and not a billion other people? By GPS coordinates? email address? static IP? irc? instant message? facebook? telephone number?
Also, how will I know when you call? Will my computer "ring"? There are hundreds of ways to solve this with regular web technology, so WebRTC would be doing you a disservice if it dictated a specific way. The context of your application will likely inform the best means of contact. Maybe I encounter you in some online forum or virtual room in an online game?
Technically speaking, you don't strictly need a signaling server with WebRTC, as long as you have other means to get an SDP offer (a piece of text) to your peer, and receive the reciprocal SDP answer in return, be it by phone text, IM, irc, email, or carrier pigeon. Try this in Chrome or Firefox: https://jsfiddle.net/nnc13tw2 - click "Offer" (wait up to 20 seconds), send the output to your friend who pastes it into the same field on their end and hits Enter, and have them send back the answer, which you paste in the answer field and hit Enter. You should now be connected, and no connecting server was ever involved.
Why the jsfiddle works: It packages all ICE candidates in the SDP, which can take a few seconds, to give you everything you need in one go.
Some advanced features, like altering the number of video sources mid-call etc. also require signaling, but once a call has been established, an app could use its own data channels for any further signaling needs between the peers.
Stackoverflow now demands that I include code to link to jsfiddle, so
I might as well include it here as well (though if you're on Chrome use the fiddle above, as camera access doesn't seem to work in snippets):
var config = { iceServers: [{ urls: "stun:stun.l.google.com:19302" }]};
var dc, pc = new RTCPeerConnection(config);
pc.onaddstream = e => v2.srcObject = e.stream;
pc.ondatachannel = e => dcInit(dc = e.channel);
v2.onloadedmetadata = e => log("Connected!");
var haveGum = navigator.mediaDevices.getUserMedia({video:true, audio:true})
.then(stream => pc.addStream(v1.srcObject = stream))
.catch(failed);
function dcInit() {
dc.onopen = () => log("Chat!");
dc.onmessage = e => log(e.data);
}
function createOffer() {
button.disabled = true;
dcInit(dc = pc.createDataChannel("chat"));
haveGum.then(() => pc.createOffer()).then(d => pc.setLocalDescription(d)).catch(failed);
pc.onicecandidate = e => {
if (e.candidate) return;
offer.value = pc.localDescription.sdp;
offer.select();
answer.placeholder = "Paste answer here";
};
};
offer.onkeypress = e => {
if (!enterPressed(e) || pc.signalingState != "stable") return;
button.disabled = offer.disabled = true;
var desc = new RTCSessionDescription({ type:"offer", sdp:offer.value });
pc.setRemoteDescription(desc)
.then(() => pc.createAnswer()).then(d => pc.setLocalDescription(d))
.catch(failed);
pc.onicecandidate = e => {
if (e.candidate) return;
answer.focus();
answer.value = pc.localDescription.sdp;
answer.select();
};
};
answer.onkeypress = e => {
if (!enterPressed(e) || pc.signalingState != "have-local-offer") return;
answer.disabled = true;
var desc = new RTCSessionDescription({ type:"answer", sdp:answer.value });
pc.setRemoteDescription(desc).catch(failed);
};
chat.onkeypress = e => {
if (!enterPressed(e)) return;
dc.send(chat.value);
log(chat.value);
chat.value = "";
};
var enterPressed = e => e.keyCode == 13;
var log = msg => div.innerHTML += "<p>" + msg + "</p>";
var failed = e => log(e);
<video id="v1" height="120" width="160" autoplay muted></video>
<video id="v2" height="120" width="160" autoplay></video><br>
<button id="button" onclick="createOffer()">Offer:</button>
<textarea id="offer" placeholder="Paste offer here"></textarea><br>
Answer: <textarea id="answer"></textarea><br><div id="div"></div>
Chat: <input id="chat"></input><br>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
Yes, signalling is mandatory so that ICE candidates and the like are exchange so that the peer connection knows who its peer is
No, how would it know its peer without some sort of exchange?
No, it does not mean that. I have done numerous experiments working with raspis, and other native devices that I stream video to a browser page through a WebRTC peer connection.
What are you talking about? You meaning the gain of using WebRTC vs Flash and a Central server? WebRTC is peer to peer and if you couple that with GetUserMedia and Html5, you get rid of the need for flash and a central media server to handle all the media exchanges.
You need a signalling server in order to be able to establish a connection between two arbitrary peers; it is a simple reality of the internet architecture in use today.
In order to contact another peer on the web, you need to first know its IP address. There's the first problem already. You need to know what the IP address of your peer is. How are you going to get this information from peer A to peer B without the people sitting at these computers calling each other via phone and dictating IP addressees? To do this, each peer discovers its own address first, then sends it to the other peer. This opens two more problems: how does a peer discover what its outwards facing IP address is (which may be significantly different than its own IP), and how does it communicate this to the other peer of yet unknown address?
This is where a signalling server comes in. Both peers have a connection to the signalling server, before they have a connection to each other. So they use the signalling server to relay messages on their behalf until they have negotiated a direct way to talk. It would be possible to negotiate a connection without 3rd party help on local subnets; but this scenario is probably rare enough that I'm not even sure the spec is addressing it.
As for 3): WebRTC can be implemented on any device, it's just a protocol; it's not tied exclusively to browsers.
As for 4): the "legacy" way of streaming anything from one browser to another always involved a relay server in the middle. This server has big CPU and bandwidth requirements and is an expensive bottleneck. WebRTC enables direct P2P connections without middleman except for a lightweight signalling server. Also, there wasn't really an open standard before; most of the time you'd be paying some money to Adobe in one way or another.
Actually it is possible, but not usable.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>webrtc</title>
</head>
<body>
<script>
let channel = null
const connection = new RTCPeerConnection({ iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] }); // ice (stun and turn) are optional
connection.ondatachannel = (event) => {
console.log('ondatachannel')
channel = event.channel
// channel.onopen = event => console.log('onopen', event);
// channel.onmessage = event => console.log('onmessage', event);
channel.onmessage = (event) => alert(event.data)
}
connection.onconnectionstatechange = (event) => (document.getElementById('connectionState').innerText = connection.connectionState) // console.log('onconnectionstatechange', connection.connectionState)
connection.oniceconnectionstatechange = (event) =>
(document.getElementById('iceConnectionState').innerText = connection.iceConnectionState) // console.log('oniceconnectionstatechange', connection.iceConnectionState)
async function step_1_initiator_create_offer() {
channel = connection.createDataChannel('data')
// channel.onopen = event => console.log('onopen', event)
// channel.onmessage = event => console.log('onmessage', event)
channel.onmessage = (event) => alert(event.data)
connection.onicecandidate = (event) => {
// console.log('onicecandidate', event)
if (!event.candidate) {
document.getElementById('createdOffer').value = JSON.stringify(connection.localDescription)
document.getElementById('createdOffer').hidden = false
}
}
const offer = await connection.createOffer()
await connection.setLocalDescription(offer)
}
async function step_2_accept_remote_offer() {
const offer = JSON.parse(document.getElementById('remoteOffer').value)
await connection.setRemoteDescription(offer)
}
async function step_3_create_answer() {
connection.onicecandidate = (event) => {
// console.log('onicecandidate', event)
if (!event.candidate) {
document.getElementById('createdAnswer').value = JSON.stringify(connection.localDescription)
document.getElementById('createdAnswer').hidden = false
}
}
const answer = await connection.createAnswer()
await connection.setLocalDescription(answer)
}
async function step_4_accept_answer() {
const answer = JSON.parse(document.getElementById('remoteAnswer').value)
await connection.setRemoteDescription(answer)
}
async function send_text() {
const text = document.getElementById('text').value
channel.send(text)
}
</script>
<table width="100%" border="1">
<tr>
<th>#</th>
<th>initiator</th>
<th>peer</th>
</tr>
<tr>
<td>step 1</td>
<td>
<input type="button" value="create offer" onclick="step_1_initiator_create_offer()" />
<input id="createdOffer" type="text" hidden />
</td>
<td></td>
</tr>
<tr>
<td>step 2</td>
<td></td>
<td>
<input id="remoteOffer" type="text" placeholder="offer from initiator" />
<input type="button" value="accept offer" onclick="step_2_accept_remote_offer()" />
</td>
</tr>
<tr>
<td>step 3</td>
<td></td>
<td>
<input type="button" value="create answer" onclick="step_3_create_answer()" />
<input id="createdAnswer" type="text" hidden />
</td>
</tr>
<tr>
<td>step 4</td>
<td>
<input id="remoteAnswer" type="text" placeholder="answer from peer" />
<input type="button" value="accept answer" onclick="step_4_accept_answer()" />
</td>
<td></td>
</tr>
</table>
<hr />
<input id="text" type="text" />
<input type="button" value="send" onclick="send_text()" />
<hr />
<table border="1">
<tr>
<th colspan="2">connection</th>
</tr>
<tr>
<th>connectionState</th>
<td id="connectionState">unknown</td>
</tr>
<tr>
<th>iceConnectionState</th>
<td id="iceConnectionState">unknown</td>
</tr>
</table>
</body>
</html>
Source: https://mac-blog.org.ua/webrtc-one-to-one-without-signaling-server
Demo
Most of the answer has been covered, just thought I'd add a little something. When Google first created webRTC and open sourced it 4 years ago, it did so strictly on it's own without any signaling capabilities.
However, recently Google purchased Firebase, so I would wager that soon they will be open sourcing a complete end-to-end solution for WebRTC so all of us can have an even easier time implementing it.
Speaking of Firebase, I tried it out and it's not bad, got the basic job done: http://antonvolt.com/prototype2/

Web API Call is not working

This is the first time I am using the Web API component in MVC 4. I just created a Web API project to manage a person details. I wrote a get function in Person Controller and called it from browser. The result is:
<ArrayOfPerson xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/WebAPITest.Models">
<Person>
<Address>Addr</Address>
<DOB>2013-05-04T00:00:00</DOB>
<ID>1</ID>
<Name>Name</Name>
</Person>
</ArrayOfPerson>
The URL is: http://localhost:3802/api/Person
Then I added a new MVC basic project to the solution and tried to call the Web API from the view page.
The code in view page is :
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<script src="~/Scripts/jquery-1.7.1.js"></script>
<script>
$(document).ready(function () {
$.ajax({
url: "http://localhost:3802/api/Person",
type: "Get",
success: function (data) {
for (var i = 0; i < data.length; i++) {
$("<tr></tr><td></td>" + data[i].Name + "</td><td></td>" + data[i].Address + "</td><td></td>" + data[i].DOB + "</td></tr>").appendTo("#tbPerson");
}
},
error: function (msg) { alert("Error"); }
});
});
</script>
<h2>Index</h2>
<table id="tbPerson">
<tr>
<th>Name</th>
<th>Address</th>
<th>DOB</th>
</tr>
</table>
But I am getting the alert box showing the Error. Can anyone help me out?
Since you added a new MVC project, it will run in a port other than 3802. So, the page URI will be something like http://localhost:<someport>/home/index. If JavaScript from this page calls the URI of your API endpoint, which is http://localhost:3802/api/Person, the request becomes a cross-origin request and browser does not allow it. For more info, take a look at http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api. There is a great MSDN article by Brock Allen on this topic - http://msdn.microsoft.com/en-us/magazine/dn532203.aspx.
Try to change url: "http://localhost:3802/api/Person"
to
url: "/api/Person"

xmlhttp request cannot load-origin null is not allowed by access control-Allow origin

i am beginner to Phonegap, here i am executing this reference code in Android Emulator and working in phonegap 2.0 to get simple output. After running this code, Logcat shows the following error:
xmlHTTPrequest cannot load http://api.careerbuilder.com/v1/jobsearch?DeveloperKey? origin null is not allowed by access control-Allow origin
here html code:
<div data-role="page" id="page1">
<div data-role="header" data-theme="b">
<p><center>Career Builder</center></p>
</div>
<div data-role="content" data-theme="d">
<input type="text" id="t1" placeholder="Location....">
<input type="button" id="but" value="Search" onclick=show()><br>
<ul id="list" data-role="listview" data-theme="a" data-filter="true">
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
$.support.cors = true;
$.mobile.allowCrossDomainPages = true;
}
function show() {
var val=document.getElementById("t1").value;
$.ajax({
type: "GET",
url: "http://api.careerbuilder.com/v1/jobsearch?&DeveloperKey= my api key",
contentType:"xml/application",
data:{
val:val,
},
dataType: "xml",
success: function(xml)
{
xmlParser(xml);
}
});
}
function xmlParser(xml) {
$(xml).find("JobSearchResult").each(function () {
var com=$(this).find("Company").text();
var job=$(this).find("JobTitle").text();
$("#list").append
('<ul><li>Company Name :' + com + '</li><li>Job Title :' + job + '</li><ul>');
$('#list').listview('refresh');
});
}
This is caused by the same-origin policies enforced by all modern browsers. Read up on how CORS works for more details. Basically the issue is that your web page is on a different domain than the careerbuilders.com URL, and the CORS headers are either not transmitted correctly by careerbuilders.com, or aren't interpreted correctly by phonegap.